复制构造函数
复制构造函数的用途就是解决:当将数据从一个对象复制到另一个对象时,其中的指针数据成员没有被正确处理的情况。
如:1
2
3
4
5
6
7
8
9
10struct Node
{
char *name;
int age;
Node(char *n=" ", int a = 0)
{
name = strdup(n); // strdup是用来分配一个新的内存并返回该指向该字符串的指针
age = a;
}
}
当这样带char *name
指针的对象,经历复制时,会遇到以下问题
1 | Node node1("node1", 10); // Create object node1 |
这里node1.name
的值跟node2.name
的值一样,是因为Node这个struct没有定义复制构造函数,导致编译器自己生成了复制构造函数。生成的复制构造函数只是逐个对成员进行复制,所以它将char *name
上面指向name字符串的指针值,即地址,复制给了node2,而不是在地址上的字符串的值。而因为age本身就是一个值,所以没被影响。
所以这里需要创建复制构造函数来解决这个问题。
1 | struct Node |
这样node1, node2之间就不会有相互影响的问题。
同样,为了完全杜绝此类问题发生,还需重载复制运算符来应对node1 = node2
这种复制方式。1
2
3
4
5
6
7
8
9
10
11Node& operator= (const Node& n)
{
if (this != &n) // 避免自己=自己还多走一步, this是一个指向自己(调用这个函数的调用对象)的指针,比如 a = b,调用对象就是a
{
if (name != 0) // 不为特殊地址/空地址
free(name); // 将指向的地址free掉
name = strdup(n.name); // 来储存新的字符串地址
age = n.age;
}
return *this;
}
所以当对象包含指针数据时,需要同时加上复制构造函数以及重载=运算符,这样所有情况就都解决了。