标签:style io color os 使用 sp for on 2014
条款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构造函数。
标签:style io color os 使用 sp for on 2014
原文地址:http://blog.csdn.net/djb100316878/article/details/41006735