Аргументы для конструктора копирования - PullRequest
6 голосов
/ 02 апреля 2020

Зачем использовать ссылки на параметры конструктора копирования?

Я нашел много информации о том, что нужно избегать неограниченных звонков, но я до сих пор не могу этого понять.

Ответы [ 3 ]

7 голосов
/ 02 апреля 2020

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

Ответ на комментарий:

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

Как и решение проблемы курицы и яйца, передача по ссылке обычно (для более крупных объектов - больше, чем размер точки) быстрее.

Ответ на дальнейший комментарий:

Вы мог бы написать своего рода конструктор копирования, передаваемый по указателю, и он работал бы так же, как и по ссылке. Но было бы неразумно вызывать явно и невозможно вызывать неявно.

Объявление:

class X
{
public:
    X();
    X(const X* const pOther);
};

Явная копия:

X x1;

X x2(&x1);  // Have to take address

Неявная копия:

void foo (X copyOfX);   // Pass by value, copy made

...

X x1;

foo (x1);  // Copy constructor called implicitly if correctly declared
           // But not matched if declared with pointer

foo (&x1); // Copy construcxtor with pointer might (?) be matched
           // But function call to foo isn't

В конечном счете, такая вещь не будет рассматриваться как конструктор копирования C ++.

5 голосов
/ 02 апреля 2020

Этот код:

class MyClass {
public:
  MyClass();
  MyClass(MyClass c);
};

не компилируется. То есть, потому что вторая строка здесь:

MyClass a;
MyClass b(a);

теоретически должна вызывать бесконечную l oop, о которой вы говорите - она ​​должна создать копию a до вызова конструктора для b. Однако, если конструктор копирования выглядит следующим образом:

  MyClass(const MyClass& c);

, то перед вызовом конструктора копирования не требуется создавать копии.

1 голос
/ 02 апреля 2020

С этой веб-страницы

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

Передавая аргумент по значению, конструктор копирования вызывает себя, входя в бесконечный «цикл рекурсии». Приведенная выше ссылка довольно хорошо объясняет основные темы о конструкторе копирования.

...