C++进阶之一


在实际工作中,发现大学C++教科书上的C++知识还不够用,或者理解不够深,为此这方面还得冲冲电。下面是简单整理了以前不太熟悉的几个点

1.     构造和拷贝函数

l   赋值构造函数:T(T &)

l   赋值拷贝函数: operator = (T &)

l   移动构造函数: T(T &&)

l   移动拷贝函数:operator =(T&&)

一般如果类中有指针成员,建议 disable 掉赋值构造和赋值拷贝函数。而通常出于对性能优化的目的,可以使用移动构造函数和移动拷贝函数来减少冗余拷贝。

举例说明:

class T {

  T(int);

T(const T&);

Operator = (const T&);

T(const T&&);

}

int main() {

   T a = T(1);

   T && b = T(2);

}

上面T a 的初始化过程中,有一次构造一次拷贝;而T b就只有一次构造了。

2.     virtual

l   限定虚函数:virtual func(….) ;

l   限定纯虚函数: virtual func(….) =0 , 抽象类只有纯虚函数

l   限定被继承的基类,用作虚基类,避免子类拥有基类中重复的成员方法;

例如: class B: virtual A;

class C: virtual A;

class D: class B, class C; // 那么D的对象中只有A的一份成员;

l   抽象类的析构函数一定是虚函数(个人的理解是对于里面的虚函数可能用到的资源是不定的)

 

3.     C++ 11 中的自动推断变量类型auto 的使用

Auto 的使用极大地方便了枚举器的使用,隐藏了枚举的过程,举例如下:

 Auto x1=3.1415169;

  Std::map<float, int> mymap;

For (auto it = mymap.begin; it != mymap.end(); it++) {

……

}

4.     C++ 匿名函数 lamnda 的使用

本质就是去类临时函数定义时的名称,通过【】代替。这种函数通常在一些算法库中的比较函数、判断是否相等的临时函数的定义中。

 格式如下:

  [capture](parameters)->return-type{body}

 

其中capture高速这个临时函数,是否以及如何使用外部的变量,规则如下:

[]        //未定义变量.试图在Lambda内使用任何外部变量都是错误的.  

[x, &y]   //x 按值捕获, y 按引用捕获.  

[&]       //用到的任何外部变量都隐式按引用捕获  

[=]       //用到的任何外部变量都隐式按值捕获  

[&, x]    //x显式地按值捕获其它变量按引用捕获  

[=, &z]   //z按引用捕获其它变量按值捕获 

 

实例如下:

【】(int a, int b->int (int z= a+b; return z);

 

5.     构造函数和析构函数执行的顺序

具体规则如下:

l   如果对象的类型是global/static 等落在.data或者.bss段,那么对于global的变量,先于main()函数执行构造;对于function domain的则在执行到的地方开始执行构造。析构函数按镜像对称的顺序进行;

l   如果对象的类型是在栈上,在执行到代码的地方开始构造,在作用域结束的地方析构;

l   如果对象的类型在堆上,根据显式调用析构函数的顺序执行;如果没有显式调用析构,在堆被系统释放的时候调用析构函数;

l   对于多重继承的情况,构造函数沿着从基类到子类的方向进行,而析构函数沿着相反方向执行。

 



猜你喜欢

转载自blog.51cto.com/xiamachao/2120810