Вот некоторый код C++:
#include <iostream>
using namespace std;
class m
{
public:
m() { cout << "mother" << endl; }
};
class n : m
{
public:
n() { cout << "daughter" << endl; }
};
int main()
{
m M;
n N;
}
Вот вывод:
mother
mother
daughter
Моя проблема состоит в том, что я не хочу, чтобы конструктор m был вызван, когда я создаю N. Что я должен сделать?
AFAIK, вы не можете удалить унаследованный конструктор.
Проблема в вашем примере связана с неправильным дизайном класса. Конструктор обычно используется для выделения ресурсов класса, установки значений по умолчанию и так далее. Он не совсем подходит для вывода чего-либо.
Вы должны поместить
n() { cout << "daughter" << endl; }
в виртуальную функцию.
В целом - если вам нужно удалить унаследованный конструктор, вам, вероятно, придется переосмыслить / изменить структуру иерархии классов.
class m
{
public:
m(bool init = true) { if (init) cout << "mother" << endl; }
};
class n : m
{
public:
n() : m(false) { cout << "daughter" << endl; }
};
или, если вы не хотите, чтобы он был общедоступным
class m
{
protected:
m(bool init) { if(init) Init(); }
Init() { cout << "mother" << endl; }
public:
m() { Init(); }
};
class n : m
{
public:
n() : m(false) { cout << "daughter" << endl; }
};
Два решения:
Не выводить n
из m
. Убедитесь, что у вас действительно есть повторное использование интерфейса (что вы полагаетесь на полиморфный интерфейс) вместо повторного использования реализации. В последнем случае лучше сделать m *
членом n
, а затем создавать объект m
только при необходимости. Это было бы моим предпочтительным решением.
Вы, вероятно, не хотите, чтобы вызывали конструктор m
, потому что он делает что-то, чего вы не хотите. Переместите тот код, который вы не хотите выполнять, из конструктора m
s в специальную функцию init ()
или подобную, а затем вызовите ее по мере необходимости. Я не рекомендую это, потому что вы получаете интерфейс с отслеживанием состояния.
Конструкторы никогда не наследуются. Что происходит, так это то, что C ++ генерирует конструктор с нулевым значением по умолчанию, который инициализирует базовые классы и члены типа класса. Базовые классы всегда инициализируются, и нет никакого способа предотвратить это, поэтому, если вы не хотите, чтобы вызывались конструкторы базового класса, не наследуйте от базового класса.
Объект любого класса содержит в себе подобъекты всех его суперклассов. И все они должны быть построены до строительства основного объекта. Часть этой конструкции вызывает один из конструкторов базового класса, и ее нельзя пропустить. Вы можете только выбрать вызываемый конструктор.