【问题标题】:Polymorphism->error: 'no known conversion from derived class to base class'多态性->错误:'从派生类到基类的未知转换'
【发布时间】:2013-11-29 02:31:52
【问题描述】:

我怎么可能这样做:

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);
    ...
};

请注意,我将其继承为 private


那我想做点什么:

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 继承为私有的原因是在公共范围内隐藏一些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?

【问题讨论】:

    标签: c++ inheritance polymorphism


    【解决方案1】:

    这不起作用的原因是私有继承不构成“是”关系。事实上,它比继承更接近组合,因为派生类获取基类的实现而不获取其接口。

    我希望某些派生类将 Base 继承为私有的原因是在公共范围内隐藏某些 Base 的成员/函数。

    那是私有继承的错误理由。 Here are some good answers to the question when you should inherit privately.

    有没有其他方法可以做,类似于这个,而不覆盖每个 Base::function()s?

    您不需要重写 Base 的每一个函数,除非它们是纯虚拟(也称为“抽象”)函数。您的基类可以为其虚函数提供空实现,以便派生类可以决定提供哪些功能。

    【讨论】:

    • 当然我不想在每个派生类上继承每个Base::functions(),但是在我的实现情况下,我应该小心Base::function()的w/c,当某些函数时我必须重写应该在公共范围内执行。既然我可以做到这一点,我认为这对我来说不是一个好的选择。
    • @mr5 请注意,您可以选择性地将某些继承函数设为私有 (demo)。
    • 我真的很喜欢将继承设为私有,这样我就可以避免太多function overridings。但是,如果我这样做了,我就不能做d2->addObject(d1); 的事情。还要提前考虑,决定是否将base member function 声明为virtual 对我来说似乎是个问题。
    • @mr5 你应该把它们都变成虚拟的:一旦你添加了第一个虚拟函数,添加更多虚拟函数的开销很小,无论是十个还是一百个。
    • @mr5 私下继承不会让您有选择地告诉哪些函数应该可用于哪些派生类。 C++ 访问控制没有这么精细的粒度。
    【解决方案2】:

    我认为你的代码应该是:

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

    正如编译器所说,不可能从 Derived1 的实例转换为指向 Base 实例的 const 指针。

    【讨论】:

    • 啊,抱歉打错了。
    【解决方案3】:

    不确定你想要什么,但多态正是这样做的,它允许你覆盖 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
    };
    

    现在您可以从 Base 对象访问派生版本的函数

    【讨论】:

    • 问题不在于function,而在于addObject
    猜你喜欢
    • 1970-01-01
    • 2021-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多