разница между реализацией конструктора копирования и конструктора - PullRequest
0 голосов
/ 08 декабря 2011

Одна из целей конструктора копирования состоит в том, чтобы указатели, объявленные в копии, указывали на их соответствующие элементы, а не просто возвращали их элементам оригиналов, но как именно это реализовано?

скажем, ваш конструктор:

foo::foo(int i)
{
    blah = i;
    bar = new whatever; //bar is a pointer to a whatever
}

так как должна выглядеть реализация конструктора копирования? это единственное, что вы должны вставить в него что-то вроде:

bar = this->whatever;

или

bar = whatever;

или он должен содержать все, что делает обычный конструктор?

Ответы [ 3 ]

1 голос
/ 08 декабря 2011

Это полностью зависит от того, что является foo, и его отношения к whatever.

Возможные варианты:

Разделение объекта

foo::foo(const foo& other) : blah(other.blah), bar(other.bar)
{ }

Создание другого объекта

foo::foo(const foo& other) : blah(other.blah), bar(new whatever)
{ }

Создание новой копии объекта

foo::foo(const foo& other) : blah(other.blah), bar(new whatever(*other.bar))
{ }
0 голосов
/ 08 декабря 2011

Если у вас нет конструктора копирования, для вас будет создан конструктор по умолчанию, который делает поверхностное копирование , где каждая переменная-член одного объекта просто присваивается другому, в отличие от глубокая копия .

Поэтому, если у вас есть указатель на динамически выделенный буфер, конструктор копирования по умолчанию собирается просто назначить этот указатель указателю копии, а не создавать свой собственныйnew буфер для указания и копирования содержимого буфера в новый.например.

class DynamicIntArray {
private:
   int *_array;
   size_t _size;

public:
   DynamicIntArray(size_t size) : _array(new int[size]), _size(size) { }

   DynamicIntArray (const DynamicIntArray &d) // copy constructor
   {
      delete[] _array;
      _array = new int[d._size];
      _size = d._size;
      std::copy(_array, d._array, d._array + d._size);
   }

   /* destructor, assignment operator, etc */
};

Если вы не создали конструктор копирования по умолчанию, то созданный по умолчанию конструктор просто назначит d._array для _array, что может вызвать серьезные проблемы.то есть.Вместо вышесказанного это будет сделано:

_array = d._array;
_size = d._size;

Обратите внимание, что если у вас есть конструктор копирования, у вас, вероятно, должны быть оператор присваивания и деструктор (посмотрите rule-of-three ).

0 голосов
/ 08 декабря 2011

Нет, конструктор копирования предназначен для копирования элементов объекта, он не имеет большого отношения к указателям, за исключением элементов.Например, если у вас есть объект point с x и y членами, вы создадите конструктор копирования

point(const point& p) : x(p.x), y(p.y) { }

, и у него может быть другой конструктор, например

point(int x_,int y_) : x(x_), y(y_) { }

Если у вас есть элемент указателя, это зависит от объекта и от того, как вы хотите с ним работать - вы можете скопировать указатель или создать другой указатель и т. Д. Зависит от данных, на которые он указывает.

...