В соответствии со стандартом 12.6.3/p1 инициализации унаследованным конструктор [class.inhctor.init] (Упор Шахта):
Когда конструктор для типа B
вызывается для инициализации объекта другого типа D
(то есть, когда конструктор был унаследован (7.3.3)), инициализация продолжается, как если бы значение по умолчанию constr uctor были использованы для инициализации объекта D
и каждого базового класса подобъекта, из которого был наследован конструктор, за исключением того, что подобъект инициализирован вызовом унаследованного конструктора . Полная инициализация считается одним вызовом функции ; в частности, инициализация наследуемых параметров конструктора секвенирована до инициализации любой части объекта D
.
Таким образом, конструкторы на самом деле не наследуются, а скорее неявно или явно вызываются соответствующим производным конструктором. Также имейте в виду, что наследуемые конструкторы просто вызывают базовые конструкторы и не выполняют инициализацию членов в производном объекте.
Для пояснения рассмотрим следующий пример:
struct Base {
Base(int);
...
};
struct Derived : Base {
using Base::Base;
...
};
выше Derived
определение класса синтаксически эквивалентны:
struct Derived : Base {
Derived(int i) : Base(i) {}
...
};
То есть using
декларация в Derived
класс неявно определяет конструктор Derived(int)
. В этом случае помните также, что если конструктор наследуется от нескольких под-объектов базового класса Derived, программа плохо сформирована.
Таким же образом вы были привести к логическому выводу, что, так как я объявлен в базовом классе конструктор копирования с использованием декларацией:
class TBase {
public:
TBase();
TBase(const TBase &);
};
class TDerived: public TBase {
public:
using TBase::TBase;
};
Я хотел бы получить следующий синтаксический эквивалент Derived
класс:
class TDerived: public TBase {
public:
TDerived() : Base() {}
TDerived(TBase const &other) : Base(other) {}
};
Однако, это не тот случай. Вы не можете «наследовать» конструктор копирования ни конструктор по умолчанию, ни конструктор перемещения. Зачем? потому что это так диктует стандарт C++.
Что вы можете сделать вместо этого, чтобы определить определенный пользователь конструктор, который будет принимать в качестве входных данных объекта базового класса:
class TDerived: public TBase {
public:
TDerived(TBase const &other) {}
};
После всех TDerived
и TBase
это разные классы, даже если первые наследует вторую.
Поскольку специальные функции-члены не наследуются? Это не имеет смысла. То, что вы закончите, не будет «конструктором копирования». –