码迷,mamicode.com
首页 > 编程语言 > 详细

effective C++ 读书笔记 条款06

时间:2014-11-11 09:24:13      阅读:191      评论:0      收藏:0      [点我收藏+]

标签: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构造函数。

 

 

 

 

effective C++ 读书笔记 条款06

标签:style   io   color   os   使用   sp   for   on   2014   

原文地址:http://blog.csdn.net/djb100316878/article/details/41006735

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!