C++-侯捷-面向对象高级编程(下)

上一篇面向对象高级编程(上)链接

P15 转换函数

可以把一个类自动转换为别的类型,如fraction转换为double

class Fraction{
public:
    ...
    operator double() const{ //常量函数,该常量就常量. 转换成任何类型都可以
        return (double)(分子/分母);
    }
}

//使用
Fraction my_frac(3,5);
double d = 4 + my_frac;//调用operator double,my_frac转为0.6


P16 非explicit单实参构造函数 non-explicit-one-argument ctor

3就是3/1,

class Fraction{
public:
    Fraction(int num,int den=1):分子(num),分母(den){}
    
    Fraction operator+(const Fraction& f){
        return Fraction(...);
    }
};
Fraction my_frac(3,5);
double d = 4 + my_frac;//调用non-explicit ctor将4转为fraction 4/1,然后调用operator+

class Fraction{
public:
    explict Fraction(int num,int den=1):分子(num),分母(den){}//不加会出现歧义
    operator double() const{ 
        return (double)(分子/分母);
    Fraction operator+(const Fraction& f){
        return Fraction(...);
    }
}
Fraction my_frac(3,5);
double d = 4 + my_frac;//4不能转换为fraction了,加法不能进行

P17 pointer-like classes

智能指针

像指针的类,用起来跟指针一样,但是有更多的机制。

链表的node也是一种pointer-like classes。
C++-侯捷-面向对象高级编程(下)_第1张图片

T& reference operator*()const{
    return (*node).data; //用*调用的时候,返回的时候node的data部分,即某个列表元素
}

T* pointer operator->() const{
    return &(operator*()); //这里返回某个列表元素的地址
}

list<Foo>::iterator ite;
*ite; //获得一个Foo object
ite->method(); //调用Foo::method;

迭代器

C++-侯捷-面向对象高级编程(下)_第2张图片

C++-侯捷-面向对象高级编程(下)_第3张图片


P18 仿函数 function-like classes

让一个类像函数被调用,只要实现()操作符即可。


P19 namespace经验谈

把区域分隔开。用::访问特定区域。


P20 类模板

用的时候要指定类型,好在创建类的时候知道T
C++-侯捷-面向对象高级编程(下)_第4张图片


P21 函数模板

设计一个函数,调用的时候编译器进行实参推导,推导出T为stone
C++-侯捷-面向对象高级编程(下)_第5张图片

P22 成员模板

更灵活地构造模板
C++-侯捷-面向对象高级编程(下)_第6张图片


P23 模板特化

把模板泛化的部分锁定

//泛化
template<class Key>
struct hash{};

//特化
template<>
struct hash<int>{
    size_t operator()(int x) cosnt{return x;}
};
cout<<hash<int>()(1000);//hash()表示是临时对象,(1000)启动operator()重载



P24 模板偏特化

  1. 个数上的偏
//泛化模板
template<typenamte T, typename Alloc=...>//模板参数 
class vector{
  ...  
};

//个数上的偏特化
template<typename Alloc=...>
class vector<bool, Alloc>{
  ...  
};

  1. 范围上的偏

任意类型缩小为指针

//泛化模板
template<typename T>
class C{
	...
};

//针对指针的偏特化模板
template<typename T>
class C<T*>{
    ...
};

c<string> obj1; //使用泛化模板
c<string*> obj2; //使用偏特化模板


P25 模板模板参数

一个模板参数本身也是一个模板,这里比较高深了,看看就行了

template <typename T,
		template<typename T> class Container
          >
class XCls{
private:
    Container<T> c;
...
};
   
//使用
template<typename T>
using Lst = list<T,allocator<T>>;
XCls<string, Lst>mylst2;


P27 c++的三个主题

数量不定的模板参数(Since C++11)

void print(){
    
}

template<typename T,typename... Types>//typename...任意个数的模板
void print(const T& firstArg,const Types&... args){//一个和一包
    cout<<firstArg<<endl;
    cout<<sizeof...(args)<<endl; //这里就知道参数包的size大小
    print(args...); //递归调用
}

//使用
print(7.5,"hello",bitset<16>(377),42); 

auto (Since C++11)

以前:

list<string> c;

list<string>::iterator it;
it = find(c.begin(),c.end(),target);

使用auto:


//auto写
list<string> c;
auto it = find(c.begin(),c.enmd(),target);//让编译器推it的类型

//如错误写法
auto it;
it = find(c.begin(),c.enmd(),target);

ranged-base for(Since C++11)

一种新的for循环方式

//临时遍历
for (int i: {2,3,4,7} ){//{2,3,4,7}也是c++11里面形成容器的方式
    cout<<i<<endl;
}

vector<double> vec;
...
for(const auto elem:vec){ //pass-by-value
    cout<<elem<<endl;
}
for(const auto& elem:vec){ //pass-by-reference
    elem*=3;
}


P28 reference 引用详解

引用就是代表,是同一块地址的别名

int x = 0;
int* p = &x; //取指针
int& r = x; //取引用,r代表x,r,x现在都是0,且地址相同

int x2 = 5;
r = x2; //覆盖赋值,即x被赋值为5
int& r2 = r; //传递性,r2同样引用x,r、x、r2都是5

传参时 指针、值、引用的比较:

void f1(Cls* pobj){pobj->xxx();}
void f2(Cls obj){obj.xxx();}
void f3(Cls& objs){obj.xxx();} //注意是不同函数,如果是同一个函数就会报错,编译器二义性错误

Cls obj;
f1(&obj);
f2(obj);//f2和f3的调用参数一致,不像指针,入参需要设置为&obj
f3(obj);


P30 关于vptr和vtbl

只要类中有虚函数,就有vptr,它指向vtbl,表里面放的都是函数指针,指向内存里面的虚函数。
C++-侯捷-面向对象高级编程(下)_第7张图片
c++编译器进行函数调用的时候,有两种形式:

  1. 静态绑定:call (汇编语言的一个动作)。
  2. 动态绑定(虚机制):要符合三个条件:1.通过指针 2.指针式向上转型(动物到猪)3调用的是虚函数.
    C++-侯捷-面向对象高级编程(下)_第8张图片

动态绑定也就是实现多态的底层原理


P31 关于this

通过一个对象调用函数,对象的地址就是this


P32 const

const在修饰成员函数时要放在()和 {}之间,表示不改变成员函数,全局函数不能这么用

当成员函数的const和non-const版本同时存在,
const object 只能调用const版本。
non-const object只能调用non-const版本。

const object不能调用non-const member function,const member function不能调用non-const member function

你可能感兴趣的:(c++,c++,开发语言)