2010-01-30 4 views
7

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

+12

Ну, это было бы типичным Шилд - почему на земле люди используют его книги? – 2010-01-30 14:39:36

+4

Пожалуйста, не берем книги Шильдта без соли. Google для термина «Bullschildt» и убедитесь сами. Более серьезно, читайте обзоры книг Шильдта по ACCU; большинство из них не являются благоприятными. –

+1

@Neil: хотя я слышал также и о книгах Шильдта, просто трудно поверить, что он не говорит о конструкторах копий. –

ответ

9

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

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 

} 
+2

Только если 'foo' имеет прототип' void foo (пример x); '. Например, 'void foo (const example & x);' не будет вызывать никаких конструкторов. Или 'void foo (int x);' который может вызывать оператор-оператор 'operator int()', если не ошибка компилятора. – kennytm

+1

Я отредактировал сообщение, чтобы включить прототип для foo(), чтобы он дал понять. – DerKuchen

+0

-1 «Конструктор копирования имеет следующую форму:» неверен. Существует четыре возможных типа конструктора копирования. Кроме того, пример класса синтаксически недействителен . –

14

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

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

4

См. Copy constructor в Википедии.

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

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

    // ... 
}; 

Данный экземпляр foo, вызовите конструктор копирования с

Foo bar(foo); 

или

Foo bar = foo; 

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

0

Ссылка на часто задаваемые вопросы по C++, добавленные Eli, хороша, и сообщение gbacon верное.

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

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

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

2

Copy конструктор будет вызван в то следующие сценарии:

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

    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

Copy Constructor является неотъемлемой частью 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; 
} 
Смежные вопросы