首页 > 代码库 > 高效C++ --经验条款(二)

高效C++ --经验条款(二)

STL迭代器以指针为根据塑造,所以迭代器的作用就像个T*指针,声明迭代器为const就像声明指针为const一样(既声明一个T* const指针),表示这个迭代器不得执行不同的东西,但它所指的东西的值是可以改动的。如果你希望迭代器所指的东西不可被改变(类似const T*指针),需要的是const_iterator。

Std::vector<int>  vec;

Const std::vector<int>::iteratoriter = vec.begin();   //iter的作用像个T* const

*iter = 10;     //没问题,可以改变iter所指物体

++iter;  //错误

Std::vector<int>::const_iteratorciter = vec.begin();  //citer的作用就是个constT*

*citer =10;  //错误  *citer是const

++citer;  //可以改变citer;

 

两个成员函数如果只是常量性不同,可以被重载。

 

Mutavble可以释放掉non-static成员变量的bitwiseconstness约束。

 

对象的成员变量的初始化动作发生在进入构造函数本体之前。在成员列表内才算是成员的初始化动作。

 

当自己写类时,对于常规的类定义的方法,我们都会为类定义一个或多个构造函数、一个析构函数、一个copy assignment操作符。如果自己没有声明,编译器就会为他声明(编译器版本的)一个copy构造函数、一个copy assignment操作符号和一个析构函数。此外如果你没有声明任何构造函数,编译器也会为你声明一个default构造函数。所有这些函数都是public和inline的。同时只有当这些函数被需要时(被调用),他们才会被编译器创建出来。编译器版本生成的copy构造函数和copy assignment操作符,编译器创建的版本只是单纯地将来源对象的每一个non-static成员变量拷贝到目标对象。

但是有一点需要注意,如果你打算在一个“内含reference成员”的class内支持赋值操作,你必须自己顶一个copy assignment操作符。也就是说,如果一个类中的成员变量有引用类型,使用编译器自动生成的copy assignemnt操作符是不可靠的。如果类中有引用成员变量或者”内含const成员”,编译器不会为类生成copy assignment操作符。如果某个base classed将copy assignment操作符声明为pirvate,编译器将拒绝为其derived classes生成一个copy assignment操作符。

 

综上所述:编译器可以暗自为class创建default构造函数、copy 构造函数、copyassignment操作符,以及析构函数。但是在有些情况下编译器不会做这些事情的。比如类中如果有引用的成员变量或者const的成员变量,如果基类的copy assignment被声明为private类型。   

所以如果不想使用编译器自动生成的函数,就该明确拒绝。如果将copy构造函数和copy assignment操作符都被声明为private而且没有定义,那么外部就不能使用拷贝构造函数和赋值构造函数了。这样就进制了对象的拷贝和赋值。

从此引申一点:

在BOOST库中有进制拷贝的类,只有子类继承了这个类,那么就会进制拷贝,为什么?嘉盛声明了一个类,

Classuncopyable{

Protected:

         Uncopuable() {}

~uncopyable(){};

Private:

         Uncopyable(const uncopyable&) ;

         Uncopyable& operator=(constuncopyable&);

};

如果子类继承了这个类,即使在子类中不声明copy构造函数或者copyassignment操作符也不会被copy构造函数或copy assignment操作符,因为编译器不会为之生成。编译器就会直接决绝为之生成默认的这些函数。就是因为base class的拷贝函数是private.

为了不让编译器自动提供这些机能,可将相应的成员函数声明为private并且不给予实现,同时使用向uncopyable这样的base class也是一种方法。

 

到此为止,就明白编译器编译器可以为某些类(没有定义copy 构造函数、没有定义构造函数、没有定义copy assignment操作符)做什么了!编译器会为之生成一个的。同时也明白编译器在什么时候不会自动生成上面的几个函数,同时知道编译器生成的这些函数在被调用的时候都做了什么。同时知道了在不需要的时候怎么禁止编译器自动生成。

高效C++ --经验条款(二)