Необходимо ли создавать конструктор копирования для производных классов? - PullRequest
2 голосов
/ 31 мая 2019

Если у меня есть базовый класс со сложным элементом данных, скажем, char*, и в конце моей цепочки наследования у меня есть другой класс с таким же типом DM, должен ли я реализовать CCTOR всех другие занятия в пути?

например:

Животный класс:

class Animal
{
    int age;
    char* name;
    Animal() { ... } 
    Animal(const Animal &animal) { ..deep copying name..}
}

Класс млекопитающих:

class Mammal : public Animal
{
    int height;
    Mammal() { ... } 
}

Лошадь Класс:

class Horse : public Mammal 
{
    char* color;
    Horse() { ... } 
    Horse(const Horse &horse ) { ..deep copying color..}
}

Нужно ли реализовывать CCTOR в Mammal, даже если в качестве элемента данных он содержит только int?

В основном мой вопрос: при копировании сложного объекта (построенного из нескольких классов) компилятор активирует CCTOR каждой части отдельно?

Edit: Чтобы было понятно, я хочу скопировать объект Horse. Если я напишу свой код, как указано выше, его имя также будет скопировано?

Ответы [ 3 ]

3 голосов
/ 31 мая 2019

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

Обратите внимание на мою мысль о «конструкторе копирования каждой переменной-члена». Конечно, конструктор копирования char* ничего не делает - но если вы поместите char* в класс с подходящим конструктором копирования, то Animal и Horse могут оба использовать этот класс для своей переменной-члена - и не будут нужен собственный конструктор копирования.

На самом деле, конечно, std::string уже предоставлен для вас (но я предполагаю, что у вас есть более сложный случай в реальности).

2 голосов
/ 31 мая 2019

Нужно ли мне внедрять CCTOR в Mammal, даже если он имеет только int в качестве члена данных?

номер

при копировании сложного объекта (построенного из нескольких классов) компилятор активирует CCTOR каждой части отдельно?

Да.

Смотри, например, https://en.cppreference.com/w/cpp/language/copy_constructor#Implicitly-defined_copy_constructor:

Для типов классов, не являющихся объединениями (class и struct), конструктор выполняет полное для всех членов копирование оснований объекта и нестатических членов в порядке их инициализации с использованием прямой инициализация.

(Акцент мой.)

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


Обратите внимание, однако, что современный стиль C ++ стремится не допустить управления членами в конструкторы. То есть, например, Horse не должен заботиться о выделении (и освобождении) памяти для color в его конструкторах (и деструкторе).

Вместо этого каждый участник должен управлять самим собой (вам придется изменить тип color на что-то другое, например, std::string), чтобы сгенерированный компилятором конструктор копирования по умолчанию и деструктор работали очень хорошо.

0 голосов
/ 31 мая 2019

Проблемными членами класса являются необработанные указатели char*.

В idiomatic c ++ вы можете решить эту проблему, используя std::string, поэтому вам не нужноукажите любые конструкторы:

class Animal
{
    int age;
    std::string name;
    Animal() = default; // not really neccessary, just for demonstration
                        // purpose
    Animal(const Animal &animal) = default; // not really neccessary, just for
                                            // demonstration purpose
};

class Mammal : public Animal
{
    int height;
};

class Horse : public Mammal 
{
    std::string color;
};
...