对象赋值
-
同一个类的对象之间可以相互赋值,默认情况下,进行的是对象成员之间的复制,也称为【按位复制】或【浅复制】。
-
当类的数据成员中没有指针类型的变量时,直接对两个对象进行赋值没有问题。
-
但是一旦类的数据成员含有指针变量,那么直接对这两个对象进行赋值操作之后,这两个对象的指针都将指向同一块内存。这时,一旦其中一个对象生存期结束,释放该内存,那么另一个对象的指针就变成了野指针!这对程序危害很大。
解决上述问题的方法就是在类中添加拷贝构造函数。
-
拷贝构造函数是一个特殊的构造函数,当采用一个对象初始化另一个对象时,将自动调用拷贝构造函数。他与构造函数唯一的区别就是,其参数是当前类的引用,而且必须是一个引用。
-
注意,拷贝构造函数能解决用一个对象初始化另一个对象的问题,其在创建对象时被调用,但是不能处理对象之间的赋值操作(对象初始化与赋值是两个不同的操作)。
class Person
{
private:
int age;
char *name;
public:
//一般构造函数
Person(char *n, int a)
{
name = new char [strlen(n)+1];
strcpy(name,n);
age = a;
}
//拷贝构造函数
Person(Person &obj)
{
name = new char [strlen(obj.name)+1];
strcpy(name,obj.name);
age = obj.age;
}
~Person()
{
delete [] name;
}
}
当执行下面这句程序时,对andrew进行初始化:
Person jack;
Person andrew = jack; //定义andrew的同时,调用拷贝构造函数对其进行初始化
Person andrew(jack); //意思和上面一句一样,都是用jack初始化andrew
将自动调用andrew的拷贝构造函数,此时,其参数obj代表jack。
拷贝构造函数被调用的情况:
- 用对象初始化同类的另一个对象时。如上面那个例子。
- 函数的形参是对象,进行参数传递时将调用拷贝构造函数。
- 函数的返回值是对象,例子如下:
//返回值是对象的函数
Person getPerson()
{
Person myPerson;
return myPerson;
}
Person andrew;
andrew = getPerson();//getperson函数执行结束时,将调用myperson的拷贝构造函数对一个临时变量进行初始化,然后再将该临时变量赋值给andrew