首页 > 代码库 > C++ Primer Plus学习笔记之拷贝构造函数

C++ Primer Plus学习笔记之拷贝构造函数

C++ Primer Plus学习笔记之拷贝构造函数

1,什么是拷贝构造函数
拷贝构造函数有两个含义:
首先,它是一个构造函数,当创建一个新对象时,系统自动调用它;
其次,它将一个已经定义过的对象的数据成员逐一对应的复制给新对象;
如果一个类没有显式定义拷贝构造函数,C++编译器可以为该类产生一个缺省的拷贝构造函数。这个缺省的拷贝构造函数采用C的方式,将拷贝对象的内存一个字节一个字节的拷贝到拷贝对象的内存中(内存拷贝);
2,拷贝构造函数的作用
(1)创建一个新对象,并将一个已存在的对象拷贝到这个新对象;
(2)对象的值做参数(将实参对象拷贝到形参对象);
(3)函数返回一个对象(拷贝返回的一个对象给一个临时对象);
3,为什么需要拷贝构造函数
我们往往会忽略为一个类显式地提供拷贝构造函数。此时C++编译器可以为该类产生一个缺省的拷贝构造函数。这个缺省的拷贝构造函数采用C的方式,将拷贝对象的内存一个字节一个字节的拷贝到拷贝对象的内存中(内存拷贝)。这样一来,新对象和老对象的内存映像是一模一样的,我们可以说,新对象是老对象的“克隆体”;
在一般情况下,这个缺省的拷贝构造函数工作得很好,但是,在一些特殊的情况下,它却表现得有问题。
请看下面的例子:
我们需要统计一个类在程序运行过程中一共实例化出对少个对象。这个工作我们可以在类中加入一个静态变量,并且在该类的构造函数中自增该变量,然后在析构函数中减计数。很明显,如果计数以0开始,那么程序结束时以0结尾。
#include<iostream>
#include<cstdlib>

using namespace std;

class Point
{
	public:
		Point(int ix=0,int iy=0)//创建对象,计数自增
		{
			x=ix;
			y=iy;
			PtCount++;
			PrintCount("In constructor...");
		}
		~Point()//对象销毁,计数自减
		{
			PtCount--;
			PrintCount("After object destroyed...");
		}
		static void PrintCount(const char *str)
		{
			cout<<str<<endl;
			cout<<"Point Count="<<PtCount<<endl;
		}
	private:
		int x;
		int y;
		static int PtCount;//用于对象计数
};

int Point::PtCount=0;

Point Fun(Point p)//形参p的缺省拷贝构造函数要被调用
{
	Point::PrintCount("In Fun()...");
	return p;
}

int main(int argc,char *argv[])
{
	Point p1;
	Point p2=Fun(p1);//p2的缺省拷贝构造函数要被调用
	p2.PrintCount("After Point2 create...");

	return 0;
}
运行结果:

In constructor...

Point Count=1

In Fun()...

Point Count=1,此时已经出错了,因为此时内存中不仅存在着p1对象,还存在着临时对象形参p;

After object destroyed...

Point Count=0

After Point2 create...

Point Count=0

After object destroyed...

Point Count=-1

After object destroyed...

Point Count=-2

解决问题的方法相当直观,就是为Point类提供一个显示 的拷贝构造函数。

#include<iostream>

using namespace std;

class Point
{
	public:
		Point(int ix=0,int iy=0)
		{
			x=ix;
			y=iy;
			PtCount++;
			PrintCount("In constructor...");
		}
		Point(const Point &p)//拷贝构造函数
		{
			x=p.x;
			y=p.y;
			PtCount++;
			PrintCount("In copy constructor...");
		}
		~Point()
		{
			PtCount--;
			PrintCount("After object destroyed...");
		}
		static void PrintCount(const char *str)
		{
			cout<<str<<endl;
			cout<<"Point Count="<<PtCount<<endl;
		}
	private:
		int x;
		int y;
		static int PtCount;
};

int Point::PtCount=0;

Point Fun(Point p)
{
	Point::PrintCount("In Fun()...");
	return p;
}

int main(int argc,char *argv[])
{
	Point p1;
	Point p2=Fun(p1);
	p2.PrintCount("After Point2 create...");

	return 0;
}
运行结果:

In constructor...

Point Count=1       p1形成

..........................................................

In copy constructor...

Point Count=2

In Fun()...

Point Count=2      形参p拷贝实参p1的结果

.........................................................

In copy constructor...

Point Count=3      p2接受Fun返回的结果

........................................................

After object destroyed...

Point Count=2      形参p销毁

........................................................

After Point2 create...

Point Count=2      p2形成

........................................................

After object destroyed...

Point Count=1      p2销毁

........................................................

After object destroyed...

Point Count=0    p1销毁

.........................................................


C++ Primer Plus学习笔记之拷贝构造函数