Объектно-ориентированное программирование, наследование, конструкторы копирования - PullRequest
4 голосов
/ 17 января 2010

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

// name will be passed to the base class constructor and 17
// is for derived class constructor.
Teacher object(“name”,17) ;
Teacher object1=object; //call to copy constructor

Теперь я не написал конструктор копирования для обоих классов, конечно, будут вызваны конструкторы копирования по умолчанию. Конструктор копирования класса Person по умолчанию сначала вызывает конструктор копирования базового класса.

Теперь проблема в том, что я пишу конструктор копирования только для базового класса, в результате конструктор копирования по умолчанию производного класса вызовет мой конструктор копирования.
Теперь предположим, что я пишу конструктор копирования для обоих классов. теперь конструктор копирования производного класса (т.е. Teacher) будет вызывать конструктор по умолчанию базового класса, но не конструктор копирования, почему?
Разве только конструктор копирования по умолчанию производного класса может автоматически вызывать конструктор копирования базового класса?

Ответы [ 3 ]

8 голосов
/ 17 января 2010

Вы должны явно вызвать конструктор базовой копии:

Teacher(const Teacher& other) 
    : Person(other) // <--- call Person's copy constructor.
    , num_(other.num_)
{
}

В противном случае будет вызываться конструктор по умолчанию Person.


Кажется, я не до конца понимаю вопрос, поэтому я просто скажу все, что считаю уместным, и, надеюсь, это поможет ОП.

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

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

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

class Base {
    int num_
public:
    Base(int n) : num_(n) { }
    // copy constructor defined by compiler
};

class Derived : public Base {
    float flt_;
public:
    Derived(float f, int n) : Base(n), flt_(f) { }
    // Copy constructor
    Derived(const Derived& other)
        : Base(other) // OK to explicitly call compiler generated copy constructor
        , flt_(other.flt_)
    {
    }
};

Подробнее см. В этой статье Википедии .

1 голос
/ 19 октября 2011
class Base {
    int num_
public:
    Base(int n) : num_(n) { }
    // copy constructor defined by compiler
};

class Derived : public Base {
    float flt_;
public:
    Derived(float f, int n) : Base(n), flt_(f) { }
    // Copy constructor
    Derived(const Derived& other)
        : Base(other) // OK to explicitly call compiler generated copy constructor
        , flt_(other.flt_)
    {
    }
};
1 голос
/ 17 января 2010

Если вы не укажете конструктор копирования, компилятор сгенерирует его автоматически. Этот конструктор генерируется так, что он вызывает конструктор копирования базового класса.

Если вы реализуете конструктор копирования самостоятельно, вы также указываете, какой конструктор базового класса следует использовать (см. Ответ Мотти). Если вы ничего не указали, используется конструктор по умолчанию (поэтому он называется «конструктор по умолчанию»: он используется, когда конструктор явно не указан).

ТАК, что компилятор автоматически генерирует разумный конструктор копирования, но если вам нужно что-то особенное, больше не происходит никакой магии, и вы должны сами указать, как именно должен выглядеть этот конструктор.

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