类的三个特殊成员Copy Constructor、Copy-Assignment Operator、Destructor重载与使用

今天看《C++ Primer》的13.1节——Copy, Assign, and Destroy

被这几个玩意儿弄得晕得不行:

◆   Copy Constructor

◆   The Copy-Assignment Operator

◆   Destructor

主要问题集中在:

◆   我们在什么时候需要自己重写?

◆   系统会在什么时候用我们重写的版本?

◆   拷贝构造和赋值操作符的区分到底是什么?

0x00 特性

为了区分他们,我们首先要分别从每一个的特性说起

这个可以参考 http://note.youdao.com/share/?id=04efd559b42f3672423b3a2f08c86899&type=note

0x01 把戏

上面那个链接其实可看可不看,因为我自己总结了一遍下来,还是弄不清楚。

必须要来点儿实际的!

0x02 学习材料

非常好的实战讲解视频 https://www.youtube.com/watch?v=F-7Rpt2D-zo&noredirect=1

0x03 一个不需要自己写以上三者的场景

在游戏设计中,我们通常需要一些角色

每个角色保护自己的特性,首先我们假设有:名字,生命值,攻击力,智力

class Character
{
public:
    Character(string name, int life, int strength, int intelligence):
      _name(name), _life(life), _strength(strength), _intelligence(intelligence){}
private:
    string _name;
    int _life;
    int _strength;
    int _intelligence;
};

如果我们需要把角色A的属性复制给角色B

int main()
{
	Character c1("Bob", 7, 5, 6);
	Character c2("Sally", 8, 6, 6);

	c1 = c2;	//调用系统装配的 Copy-Assignment Operator
}

0x04 变为需要自己写的场景

现在,我们为角色增加一项属性:物品栏

同样,把角色A的属性复制给角色B,如果我们继续使用系统默认的版本,则系统只把指针的内容拷贝给c1

至于内容嘛……共享堆上的……

c1=c2;

这种赋值称作:

危险之处在于,如果我们角色复制完成后,删除角色c2的内容,那么此时c1的工具也全没了!!!

设想这是RPG游戏的角色交易与重绑定,那么……就等着被玩家投诉死吧!!!

#include <iostream>
#include <string>

#define TOOL_SIZE 5

using namespace std;

class Tool
{
public:
	Tool()
	{
		for (int i = 0; i < TOOL_SIZE; i++)
		{
			_tool[i] = 0;
		}
	}

	void set_tool1(int tool[TOOL_SIZE])
	{
		for (int i = 0; i < TOOL_SIZE; i++)
		{
			_tool[i] = tool[i];
		}
	}
private:
	int _tool[TOOL_SIZE];
};

class Character
{
public:
	Character(string name, int life, int strength, int intelligence, Tool* toolArray):
	  _name(name), _life(life), _strength(strength), _intelligence(intelligence), _toolArray(toolArray){}

private:
	string _name;
	int _life;
	int _strength;
	int _intelligence;
	Tool* _toolArray;
};

int main()
{
	Tool *t1 = new Tool;
	int tool1[5] = {11,0,0,0,0};
	t1->set_tool1(tool1);

	Tool *t2 = new Tool;
	int tool2[5] = {21,22,23,0,0};
	t2->set_tool1(tool2);

	Character c1("Bob", 7, 5, 6, t1);
	Character c2("Sally", 8, 6, 6, t2);

	c1 = c2;			//调用系统装配的 Copy-Assignment Operator
	Character c3 = c2;	//调用系统装配的 Copy Constructor

	return EXIT_SUCCESS;
}

A: 如果我们想通过

c1=c2;

得到如下结果就要重载 opreator=

B: 如果我们想通过

Character c3 = c2;

得到如下结果就要重载 拷贝构造函数

WHY? 因为 opreator= 仅在对象已存在时调用!

前面还提到了删除角色c2的问题,如果我们用了完全拷贝,那么删除时如果用系统装配的析构函数,会产生垃圾

此时,就需要自己写Destructor来delete他们

综上,为了漂亮地完成游戏角色的复制、删除问题:

而这,恰好就是 Rule of Three.

#include <iostream>
#include <string>

#define TOOL_SIZE 5

using namespace std;

class Tool
{
public:
	Tool()
	{
		for (int i = 0; i < TOOL_SIZE; i++)
		{
			_tool[i] = 0;
		}
	}

	Tool(const Tool &t)
	{
		for (int i = 0; i < TOOL_SIZE; i++)
		{
			_tool[i] = t._tool[i];
		}
	}

	void set_tool(int tool[TOOL_SIZE])
	{
		for (int i = 0; i < TOOL_SIZE; i++)
		{
			_tool[i] = tool[i];
		}
	}

	int get_tool(int index)
	{
		return _tool[index];
	}
private:
	int _tool[TOOL_SIZE];
};

class Character
{
public:
	Character(string name, int life, int strength, int intelligence, Tool* toolArray):
	  _name(name), _life(life), _strength(strength), _intelligence(intelligence), _toolArray(toolArray){}

	Character(const Character &c):
	  _name(c._name), _life(c._life), _strength(c._strength), _intelligence(c._intelligence), _toolArray(new Tool(*(c._toolArray)))
	{
		cout << "Copy Constructor Called!\n";
	}

    Character& operator=(const Character &c)
	{
		_name			= c._name;
		_life			= c._life;
		_strength		= c._strength;
		_intelligence	= c._intelligence;
		_toolArray		= new Tool(*(c._toolArray));

		cout << "Copy-Assignment Operator Called!\n";
		return *this;
	}

	Tool* get_tool_array()
	{
		return _toolArray;
	}

	~Character()
	{
		delete _toolArray;
	}

private:
	string _name;
	int _life;
	int _strength;
	int _intelligence;
	Tool* _toolArray;
};

int main()
{
	Tool *t1 = new Tool;
	int tool1[5] = {11,0,0,0,0};
	t1->set_tool(tool1);

	Tool *t2 = new Tool;
	int tool2[5] = {21,22,23,0,0};
	t2->set_tool(tool2);

	Character c1("Bob", 7, 5, 6, t1);
	Character c2("Sally", 8, 6, 6, t2);

	c1 = c2;			//调用系统装配的 Copy-Assignment Operator
	Character c3 = c2;	//调用系统装配的 Copy Constructor

	return EXIT_SUCCESS;
}

(完)

时间: 2024-12-20 01:10:06

类的三个特殊成员Copy Constructor、Copy-Assignment Operator、Destructor重载与使用的相关文章

C++-copy constructor、copy-assignment operator、destructor

对于一个类来说,我们把copy constructor.copy-assignment operator.move constructor.move-assignment operator.destructor统称为copy control. 今天我们先来聊聊其中的copy constructor.copy-assignment operator的destructor这三个. copy constructor copy constructor:一个constructor如果他的第一个参数是对类的

15.含有指针成员的类的拷贝(copy constructor)

http://zhedahht.blog.163.com/blog/static/25411174200722710364233/ http://www.cnblogs.com/t427/archive/2012/08/10/2633133.html http://blog.csdn.net/gamecreating/article/details/5382902 http://www.cppblog.com/xczhang/archive/2008/01/21/41569.html 题目:下面

const成员-拷贝构造函数(copy constructor)

const成员 const成员:被const修饰的成员变量.非静态成员函数 必须类里面初始化 class Car { public: const int m_price = 0; //const常量设置 Car() :m_price(0) {} //也可以在构造函数中初始化 void run() const { //const一般写最后 cout << "run()" << endl; m_price = 10; } }; const成员函数 两个同名函数构成了

类的三种成员与继承

对于类而言,一共有三种成员类型,分别为private,protected,public.其中,如果数据成员的类型为private,可以默认不写.对于在类外使用的情况,private和protected是一致的,均不可以由外部直接访问,而public所包含的成员是可以由外部直接访问的.下面给出一个基本的例子. 12345678910111213141516171819202122 class Time { private: int hour; int minute; protected: int

Copy constructor拷贝构造函数

翻译的是wikipedia关于copy constructor,地址:点击打开链接 拷贝构造函数是C++语言中用一个已有对象创建一个新对象的特殊构造函数,该函数的第一个参数必须是函数所在类型的引用(译注:const/non-const都可以,可以有多个参数剩余参数必须有默认值,一定要是引用,这些原因见后,问:有多个参数拷贝构造如何调用?). 通常编译器会自动为每一个class创建一个拷贝构造函数(显示拷贝构造);有些情况下程序员自定义了拷贝构造函数(用户自定义拷贝构造),这时编译器不合成拷贝构造

C++ Copy Constructor in depth (深入理解C++拷贝构造函数)

The copy constructor is a special kind of constructor which creates a new object which is a copy of an existing one, and does it efficiently. (拷贝构造函数是一种特别的构造函数,用于复制已经存在的对象到新生成的对象,这是一种高效的方式.) Here below is a simple declaration of a copy constructor: (

QT开发(二十九)——QT常用类(三)

QT开发(二十九)--QT常用类(三) 一.QImage 1.QImage简介 QT中提供了四个处理图像数据的类:QImage.QPixmap.QBitmap.QPicture. QImage提供了允许直接访问像素数据的硬件无关的图像显示方案,能够用作绘图设备. QImage专门为I/O.直接像素访问操作而设计,并进行了优化.访问图片的像素或是修改图片像素,则需要使用QImage,或者借助于QPainter来操作像素. 由于QImage继承自QPaintDevice,QPainter可以直接在Q

C++中关于继承中constructor、copy constructor、copy assignment的一些笔记

1.如果成员初值列不包含基类,则constructor.copy constructor  都隐式的调用基类无参的constructor 2.派生类默认的copy constructor.copy assignment会调用基类的  相应成员.而自己定义的则不会. 3.如果基类的copy assignment为private,则派生类不会生成默认的  copy assignment

(C++)关于拷贝构造函数 Copy Constructor

题目: In which of the following scenarios is a Copy Constructor called or invoked? A.    When no conversion function exists for converting the class object to another class object B.    When an existing object is assigned an object of its own class C.