Что такое конструктор копирования в C ++? - PullRequest
7 голосов
/ 30 января 2010

На странице 6 Скотта Мейерса Effective C ++ определен термин «конструктор копирования». Я использовал книгу Шилтда в качестве справочного материала и не могу найти упоминаний о конструкторах копирования. Я понял, но является ли это стандартной частью C ++? Будут ли такие конструкторы вызываться при передаче класса по значению?

Ответы [ 6 ]

14 голосов
/ 30 января 2010

Да, конструкторы копирования, безусловно, являются неотъемлемой частью стандарта C ++. Узнайте больше о них (и других конструкторах) здесь (C ++ FAQ).

Если у вас есть книга на C ++, которая не учит о конструкторах копирования, выбросьте ее. Это плохая книга.

10 голосов
/ 30 января 2010

Конструктор копирования имеет следующую форму:

class example 
{
    example(const example&) 
    {
        // this is the copy constructor
    }
}

В следующем примере показано, где он вызывается.

void foo(example x);

int main(void)
{
    example x1; //normal ctor
    example x2 = x1; // copy ctor
    example x3(x2); // copy ctor

    foo(x1); // calls the copy ctor to copy the argument for foo

}
4 голосов
/ 30 января 2010

См. Конструктор копирования в Википедии.

Основная идея заключается в том, что конструкторы копирования создают новые экземпляры путем копирования существующих:

class Foo {
  public:
    Foo();                // default constructor
    Foo(const Foo& foo);  // copy constructor

  // ...
};

Для данного экземпляра fooвызовите конструктор копирования с помощью

Foo bar(foo);

или

Foo bar = foo;

Контейнеры стандартной библиотеки шаблонов требуют, чтобы объекты были копируемыми и назначаемыми, поэтому, если вы хотите использовать std::vector<YourClass>, обязательноопределить соответствующий конструктор копирования и operator=, если сгенерированные компилятором значения по умолчанию не имеют смысла.

2 голосов
/ 05 декабря 2013

Конструктор копирования будет вызываться в следующих сценариях:

  • При создании новых объектов из существующего объекта.

    MyClass Obj1;
    MyClass Obj2 = Obj1; // Here assigning Obj1 to newly created Obj2
    

    или

    MyClass Obj1;
    MyClass Obj2(Obj1);
    
  • При передаче объекта класса по значению.

    void NewClass::TestFunction( MyClass inputObject_i )
    {
      // Function body
    }
    

    Над объектом MyClass передается значение. Так будет вызывать конструктор копирования MyClass. Передача по ссылке, чтобы избежать вызова конструктора копирования.

  • При возврате объектов по значению

    MyClass NewClass::Get()
    {
      return ObjMyClass;
    }
    

    Выше MyClass возвращается по значению, поэтому вызовет конструктор копирования MyClass. Передача по ссылке, чтобы избежать вызова конструктора копирования.

1 голос
/ 09 января 2015

Конструктор копирования является неотъемлемой частью C ++. Даже если любой компилятор C ++ предоставляет конструктор копирования по умолчанию, если он вообще не определен явно в классе, мы пишем конструктор копирования для класса по следующим двум причинам.

  1. Если в классе есть динамическое распределение памяти.
  2. Если мы используем переменные-указатели внутри класса. (иначе это будет мелкая копия в какие 2 объекта будут указывать на одну и ту же ячейку памяти.)

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

Синтаксис конструктора копирования будет выглядеть так:

class Sample{

public:
   Sample (const Sample &sample);

};

int main()
{

   Sample s1;
   Sample s2 = s1;   // Will invoke Copy Constructor.
   Sample s3(s1);     //This will also invoke copy constructor.

   return 0;
}
0 голосов
/ 30 января 2010

Хорошая ссылка на C ++ FAQ, опубликованная Eli, и сообщение gbacon верное.

Чтобы явно ответить на вторую часть вашего вопроса: да, когда вы передаете экземпляр объекта по значению, конструктор копирования будет использоваться для создания локального экземпляра объекта в области вызова функции. Каждый объект имеет «конструктор копирования по умолчанию» (gbacon ссылается на это как «сгенерированный компилятором по умолчанию»), который просто копирует каждый элемент объекта - это может быть не то, что вам нужно, если ваши экземпляры объекта содержат указатели или ссылки, например. *

Что касается хороших книг для (пере) изучения C ++ - я впервые выучил его почти два десятилетия назад, и с тех пор он сильно изменился - я рекомендую Брюса Экеля «Мышление в C ++» версии 1 и 2, свободно доступного здесь ( как в формате PDF, так и в формате HTML):

http://www.ibiblio.org/pub/docs/books/eckel/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...