Переопределить или удалить унаследованный конструктор - PullRequest
5 голосов
/ 01 июля 2010

Вот код 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. Что мне делать?

Ответы [ 5 ]

12 голосов
/ 01 июля 2010

AFAIK, вы не можете удалить унаследованный конструктор.

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

Вы должны поставить

n() { cout << "daughter" << endl; }

В виртуальную функцию.

В общем - если вам нужно удалить унаследованный конструктор, вам, вероятно, нужно переосмыслить / перестроить иерархию классов.

1 голос
/ 01 июля 2010

Конструкторы никогда не наследуются.Что происходит, так это то, что C ++ генерирует нулевой конструктор по умолчанию, который инициализирует базовые классы и члены типа класса.Базовые классы всегда инициализируются, и предотвратить это невозможно, поэтому, если вы не хотите, чтобы вызывались конструкторы базового класса, не наследуйте от базового класса.

1 голос
/ 01 июля 2010
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; }
};
0 голосов
/ 01 июля 2010

Объект любого класса содержит в себе подобъекты всех своих суперклассов. И все они должны быть построены до строительства основного объекта. Часть этой конструкции вызывает один из конструкторов базового класса, и его нельзя опускать. Вы можете выбрать только конструктор для вызова.

0 голосов
/ 01 июля 2010

Два решения:

  1. Не выводите n из m. Убедитесь, что у вас действительно есть повторное использование интерфейса (что вы полагаетесь на полиморфный интерфейс) вместо повторного использования реализации. В последнем случае предпочтительнее сделать член m* членом n, а затем создавать объект m только при необходимости. Это было бы моим предпочтительным решением.

  2. Вы, вероятно, не хотите, чтобы вызывался конструктор m, потому что он делает то, что вам не нужно. Переместите тот код, который вы не хотите выполнять, из конструктора m в выделенную функцию init() или тому подобное, и затем вызывайте его по мере необходимости. Я не рекомендую это, потому что у вас получится интерфейс с отслеживанием состояния.

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