Полиморфизм-> ошибка: «нет известного преобразования из производного класса в базовый класс»

0

Как я могу это сделать:

class Base
{
public:
    int a, b, c;
    void function();
    ...
};

class Derived1 : 
    private Base
{
public:
    int d, e, f;
    ...
};

class Derived2 :
    private Base
{
public:
    void addObject(const Base* obj);
    ...
};

Обратите внимание, что я наследую его как частный


Тогда я хотел бы сделать так:

Base* d1 = new Derived1();
Base* d2 = new Derived2();

d2->addObject(d1);

И вот соответствующая проблема, которую я получаю от компилятора:

C:\test\test.cpp||In function 'void init()':|
C:\test\test.cpp|423|error: no matching function for call to 'Derived2::addObject(const Base*)'|
C:\test\test.cpp|423|note: candidate is:|
C:\test\test.h|29|note: void Derived2::addObject(const Base*)|
C:\test\test.h|29|note:   no known conversion for argument 1 from 'Derived1 {aka ... }' to 'const Base* {aka ... }'|
||=== Build finished: 1 errors, 0 warnings (0 minutes, 9 seconds) ===|

Причина, по которой я хочу наследовать Base как private некоторыми производными классами, заключается в том, чтобы скрыть некоторые Base элементы/функции в общедоступной области.

Я не хочу напрямую обращаться к некоторым Base::functions() в общедоступной области, но еще вместо этого использовал Derived::function() чтобы манипулировать своими членами данных и позволить производному классу решить, какое действие он будет выполнять.

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

Я имею в виду:

class Base
{
public:
    //I must think in advance deciding whether if it'll be virtual or not.
    [virtual] void f1(int);
    [virtual] void f2(int);
    [virtual] void f3(int);
    //and many more...
};

class Derivedn :
    private Base
{
public:
    //hmm, I should not neglect to override certain base' member functions
    //that I don't want to access in public scope.
    void f1(int);
};

Я хочу избежать этого, но...

Есть ли другой способ, который я могу сделать, подобный этому, без переопределения каждой Base::function() s?

Теги:
polymorphism
inheritance

3 ответа

2

Причина, по которой это не работает, заключается в том, что наследование в частном порядке не является "отношением". На самом деле, это намного ближе к составу, чем наследование, потому что производный класс приобретает реализацию базы, не приобретая ее интерфейса.

Причина, по которой я хочу наследовать базу как private некоторыми производными классами, заключается в том, чтобы скрыть некоторые базовые элементы/функции в общедоступной области.

Это неправильная причина для наследования в частном порядке. Вот несколько хороших ответов на вопрос, когда вы должны наследовать конфиденциально.

Есть ли другой способ, который я могу сделать, подобный этому, без переопределения каждой Base :: function() s?

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

  • 0
    Конечно, я не хочу наследовать каждый Base::functions() на каждом производном классе, но в моем случае реализации, я должен быть осторожен с Base::function() я должен переопределить, когда определенные функции должны выполнять в публичном объеме. Так как я могу сделать это, я думаю, что это не очень хороший выбор в моем случае.
  • 0
    @ mr5 Обратите внимание, что вы можете выборочно сделать некоторые унаследованные функции приватными ( демо ).
Показать ещё 6 комментариев
0

Я думаю, что ваш код должен читать:

d2.addObject(&d1); // Note the "&"

Как компилятор говорит, нет никакого возможного преобразования из экземпляра Derived1 в указатель const к экземпляру Base.

  • 0
    Ах, извините, это опечатка.
  • 1
    Компилятор сообщает ту же ошибку без опечатки?
Показать ещё 1 комментарий
0

Не уверен, что вы хотите, но полиморфизм делает именно это, позволяя вам переопределить базовую функцию в классе Derived:

class Base
{
public:
    int a, b, c;
    virtual void function();
    ^^^^^^^
    ...
};

class Derived1 : 
    public Base
{
public:
    int d, e, f;
    virtual void function(); // do derived version of Base::function
};

и теперь вы можете получить доступ к производной версии функции из базовых объектов

  • 0
    Проблема не в function а в addObject .

Ещё вопросы

Сообщество Overcoder
Наверх
Меню