为需要动态分配内存的类声明一个拷贝构造函数和一个赋_冷月葬花魂_新浪博客

// 一个很简单的string类
class string {
public:
  string(const char *value);
  ~string();

  ...                           // 没有拷贝构造函数和operator=

private:
  char *data;
};

string::string(const char *value)
{
  if (value) {
    data = new char[strlen(value) + 1];
    strcpy(data, value);
  }
  else {
    data = new char[1];
    *data = '\0';
  }
}

inline string::~string() { delete [] data; }


这个类里没有声明赋值操作符和拷贝构造函数。这会带来一些不良后果。

 

如果这样定义两个对象:

string a("hello");
string b("world");

其结果就会如下所示:

a:  data——> "hello\0"
b:  data——> "world\0"

对象a的内部是一个指向包含字符串"hello"的内存的指针,对象b的内部是一个指向包含字符串"world"的内存的指针。如果进行下面的赋值:

b = a;

 

如果这样定义两个对象:

string a("hello");
string b("world");

其结果就会如下所示:

a:  data——> "hello\0"
b:  data——> "world\0"

对象a的内部是一个指向包含字符串"hello"的内存的指针,对象b的内部是一个指向包含字符串"world"的内存的指针。如果进行下面的赋值:

b = a;

{dy},b曾指向的内存永远不会被删除,因而会永远丢失。这是产生内存泄漏的典型例子。

第二,现在a和b包含的指针指向同一个字符串,那么只要其中一个离开了它的生存空间,其析构函数就会删除掉另一个指针还指向的那块内存。

 

string a("hello");                 // 定义并构造 a

                                 // 开一个新的生存空间
  string b("world");               // 定义并构造 b

  ...

  b = a;                           // 执行 operator=,
                                   // 丢失b的内存

                                 // 离开生存空间, 调用
                                   // b的析构函数

string c = a;                      // c.data 的值不能确定!
                                   // a.data 已被删除

 

 

 

 

例子中{zh1}一个语句调用了拷贝构造函数,因为它也没有在类中定义,c++以与处理赋值操作符一样的方式生成一个拷贝构造函数并执行相同的动作:对对象里的指针进行逐位拷贝。这会导致同样的问题,但不用担心内存泄漏,因为被初始化的对象还不能指向任何的内存。比如上面代码中的情形,当c.data用a.data的值来初始化时没有内存泄漏,因为c.data没指向任何地方。不过,假如c被a初始化后,c.data和a.data指向同一个地方,那这个地方会被删除两次:一次在c被摧毁时,另一次在a被摧毁时。

 


 

void donothing(string localstring) {}

string s = "the truth is out there";

donothing(s);


 

因为被传递的localstring是一个值,它必须从s通过(缺省)拷贝构造函数进行初始化。于是localstring拥有了一个s内的指针的拷贝。当donothing结束运行时,localstring离开了其生存空间,调用析构函数。其结果也将是:s包含一个指向localstring早已删除的内存的指针。

顺便指出,用delete去删除一个已经被删除的指针,其结果是不可预测的。所以即使s永远也没被使用,当它离开其生存空间时也会带来问题。

解决这类指针混乱问题的方案在于

只要类里有指针时,就要写自己版本的拷贝构造函数和赋值操作符函数。在这些函数里,你可以拷贝那些被指向的数据结构,从而使每个对象都有自己的拷贝


 

 

已投稿到:
郑重声明:资讯 【为需要动态分配内存的类声明一个拷贝构造函数和一个赋_冷月葬花魂_新浪博客】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——