代码改变世界

Effective C++ 学习笔记(8)

2011-04-14 10:49  Daniel Zheng  阅读(232)  评论(0编辑  收藏  举报

为需要动态分配内存的类声明一个拷贝构造函数和一个赋值操作符

  下面是一个表示String对象的类:

    class String

    {

    public:

      String(const char *value);

      ~String();

      ...

    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;

  由于自定义的operator=,C++会生成并调用一个缺省的operator=操作符。这个缺省的操作符会完成a到b成员的逐个赋值操作,包括对指针。结果如下:

    a: data->"Hello\0"

    b: data->"Hello\0"

           "World\0"

  这种情况存在如下两个问题:

    第一,b曾经指向的内存永远不会删除,造成内存泄露。

    第二,a与b的指针指向同一内存地址,如果a的析构函数被调用,那么b也将丢失数据。