首页 > 代码库 > effective C++ 读书笔记 条款06
effective C++ 读书笔记 条款06
条款06:若不想使用编译器自动生成的函数,就该明确拒绝;
直接看代码与注释:
#include <iostream>using namespace std;class Test{public: Test() { } ~Test() { }/* void TT() { Test t1; Test t2(t1); }*/private: Test(const Test& test); Test& operator = (const Test& test);};int main(){ Test t1;// t1.TT(); //编译可以通过,运行不能通过;链接器发出抱怨。// Test t2(t1); //不能够编译通过,阻止调用copy构造函数与copy = 操作符 return 0;}/*时间:2014-11-6 17:20:04说明: 若不想使用编译器自动生成的函数,就应该明确的拒绝 房地产卖的房子,每一个房子都是独一无二的; class HomeForSale{}; 对于这个类不希望发生下面的情况: HomeForSale h1; HomeForSale h2; HomeForSale h3(h1); //这个情况应该被拒绝 h2 = h1; //这个情况也应该被拒绝 通常我们不希望class支持某一个特定的功能,我们只要不声明它就可以了;但是这个策略对于copy构造函数和copy assignment操作符 却不起作用,因为条款5 已经指出,如果你不声明他们,而某些人尝试调用它们,编译器会为你声明它们。 怎么解决呢? 答案就是: 所有编译器自己产生的函数都是public的,为了阻止这些函数被创建出来,我们必须自行声明它们,但是我们不声明public,我们将它们 声明为private;让这些函数为private,我们成功阻止别人调用。 但是上面的方法绝对安全吗?不是的,虽然声明为private,但是在类的内部,类的成员函数和友元函数还是可以调用我们写的private函数, 那这个怎么解决呢? 采用的方法就是 :只声明不去定义。这样如果某些人不慎调用其中任何一个,会获得一个链接错误; 这种方法叫做: 将成员函数声明为private而且故意不实现它们。 这种方法被大家广泛接受。*/
第二种方法:
#include <iostream>using namespace std;class Uncopyable{protected: //允许子类对象构造和析构 Uncopyable(){} ~Uncopyable(){}private://但是阻止copying Uncopyable(const Uncopyable&); Uncopyable& operator = (const Uncopyable&);};//为了阻止测试对象被拷贝,我们唯一需要做的就是继承Uncopyable;class Test : public Uncopyable{};int main(){ Test t1;// Test t2(t1); //报错:class 'Test' : no copy constructor available return 0;}/*上面的方法:将成员函数声明为private而且故意不去实现它;这个方法很有效,唯一的缺点就是在链接器才可以发现它的错误将链接器错误移动到编译器是可能的而且是很好的想法:class Uncopyable{ protected: //允许子类对象构造和析构 Uncopyable(){} ~Uncopyable(){} private://但是阻止copying Uncopyable(const Uncopyable&); Uncopyable& operator = (const Uncopyable&); }; //为了阻止测试对象被拷贝,我们唯一需要做的就是继承Uncopyable; class Test : public Uncopyable{};上面的代码,只要任何人甚至是成员函数或者友元函数尝试拷贝Test对象,编译器便试着生成一个copy构造函数和copy assignment操作符,条款12当中说,这些函数的“编译器生成版”会尝试调用其 基类的对应兄弟,那些调用会被拒绝,因为其基类的拷贝构造函数是 private*//*时间:2014-11-6 17:43:17说明总结: 如果不想使用编译器自动提供的copy构造函数和copy assigment 操作符,可将其生命为private并且不予与实现; 使用像Uncopyable这样的base calss 也是一种做法。!!*/
这里说明一个我的读书笔记条款20中的一个理解错误,书中说会调用父类的copy构造函数,而我证明会调用子类的copy构造函数,这里发现原来调用那个的copy
构造函数与子类当中是否实现copy构造函数有关:
#include <iostream>using namespace std;class Base{public: Base(){ cout<<"调用父类的无参构造函数"<<endl; } ~Base(){} Base(const Base& b){ cout<<"调用父类的拷贝构造函数"<<endl; } Base& operator = (const Base& b){}};class Test : public Base{public: Test() { cout<<"调用子类的无参构造函数"<<endl; } ~Test(){} Test(const Test& t) { cout<<"调用子类的copy构造函数"<<endl; }};int main(){ Test t1; Test t2(t1); /*Test t1; 调用父类的无参构造函数 调用子类的无参构造函数Test t2(t1); 调用父类的无参构造函数 调用子类的copy构造函数 <span style="color:#ff0000;">当子类当中没有自己编写的 copy构造函数的时候,这里会调用父类的copy构造函数; 当子类当中编写了自己的copy构造函数的时候,这里调用的是父类的无参构造函数,调用子类的copy构造函数。</span> */ return 0;}
当子类当中没有自己编写的 copy构造函数的时候,这里会调用父类的copy构造函数;
当子类当中编写了自己的copy构造函数的时候,这里调用的是父类的无参构造函数,调用子类的copy构造函数。
effective C++ 读书笔记 条款06
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。