Переопределите или удалите наследованного конструктора

Вот некоторый код 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. Что я должен сделать?

6
задан Mike Seymour 1 July 2010 в 10:44
поделиться

5 ответов

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

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

Вы должны поместить

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

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

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

12
ответ дан 8 December 2019 в 18:32
поделиться
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; }
};
1
ответ дан 8 December 2019 в 18:32
поделиться

Два решения:

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

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

0
ответ дан 8 December 2019 в 18:32
поделиться

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

0
ответ дан 8 December 2019 в 18:32
поделиться

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

0
ответ дан 8 December 2019 в 18:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: