关于类中有new初始化的指针成员.可能出现的问题
分享的内容
- 默认拷贝(复制)构造函数、赋值运算符,以及显式拷贝构造函数、赋值运算符
- int* p = new int[0]
- algrithm库中的sort函数
拷贝(复制)构造函数、赋值运算符
类对象的成员经常需要动态分配内存。例如int* path.用于保存遍历的节点,申请不同的字节长度满足规模大小不同的需求。
如同默认构造函数,当没有定义拷贝(复制)构造函数、赋值运算符时,系统提供默认的拷贝(复制)构造函数、赋值运算符,但是只是简单地将一个对象的数据成员给另一个对象的数据成员进行初始化/赋值(浅拷贝)。当成员有指针时,指针的值(指向的内存块地址)也会一致,两个指针就指向同一内存块。需要显式定义,在函数中重新申请内存(深拷贝),让指针指向申请的内存块,再赋值。
错误的程序例子:
#include <iostream>
#include <string>
using namespace std;
class Test
{
public:
Test();
Test(int n);
~Test();
void show();
private:
int length;
int* path;
};
Test::Test():
length(0)
{
cout << "Copy_String::Default Constrution Called." << endl;
path = NULL;
}
Test::Test(int n)
{
cout << "Copy_String::Constrution Called." << endl;
length = n;
path = NULL;//看上去可能多此一举,但是如果new数据内存分配失败,还可以在其他地方先行判断if(path==NULL)
path = new int[n];
if (path != NULL)
{
int i;
for (i = 0; i < length; i++)
{
path[i] = i;
}
}
else {
cout << "path[] alloc failed.\n";
}
}
Test::~Test()
{
cout << "Copy_String::Destruction Called." << endl;
cout << endl;
if (path != NULL)
{
delete[] path;
path = NULL;
}
}
void Test::show()
{
cout << "length:" << length << endl;
cout << "path:";
int i;
for (i = 0; i < length; i++)
{
cout << path[i] << " ";
}
cout << endl;
cout << "path.address = " << path << endl;
}
int main()
{
cout << "无参构造函数.构造对象a" << endl;
Test a;
a.show();
cout << endl;
{
cout << "默认赋值运算符.带参对象c给对象a赋值.对象c在函数体内\n";
Test c(5);
a = c;
cout << "c.show()\n";
c.show();
cout << "a.show()\n";
a.show();
cout << endl;
}
cout << "对象c生命周期结束...";
cout << "a.show()\n";
a.show();
cin.get();
return 0;
}
程序输出:
对象c和