-2

下面的代码不是为我编译的......

class Base
{
public:
    Base(){}
    virtual void Display()
    {
        cout << "Base Display" << endl;
    }
};

class Derived : private Base
{
private:
    void Display() override
    {
        cout << "Derived Display" << endl;
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    Derived d;
    d.Display();
    Derived* dp = new Derived();
    dp->Display();

    delete dp;
    return 0;
}

调用时编译器报告错误Derived::Display()。怎么称呼它?我们可以通过编写这样的代码来解决什么样的问题?

4

6 回答 6

4

您不能从类外部访问私有方法。因此编译错误。

于 2013-09-30T17:05:04.580 回答
3

您在这里混合了两个不同的概念,成员函数的访问说明符和基类的访问说明符。

您不能调用成员函数,因为它的访问说明符 isprivate并且您正试图从不是朋友的函数中调用。这与继承的类型无关,Base即使存在这种关系。

继承关系中的访问说明符决定了代码的哪些部分可以将您的类型视为 a Base,哪些不能。在这种特殊情况下,Derived您可以在 inside 及其朋友使用引用或指针,Derived就好像它是 a 一样Base,但不能在它之外使用。

怎么称呼它?我们可以通过编写这样的代码来解决什么样的问题?

私有继承模型通过使用第三方库/类层次结构来实现,并且可以用于提供一些功能,您自己的类型在概念上不需要派生。避免公共继承会阻止您的用户将您视为基础,这是有意的,因为这是实现的细节。在您自己的类型中,您可以使用继承关系:

void detail(Base *base) {
    base->Display();       // Base::Display is public
}
void Derived::show() {     // Derived::show is public:
    detail(this);          // Private inheritance is visible inside Derived
}
于 2013-09-30T17:09:03.573 回答
2

您已Display在派生类中设为私有,因此可以通过指针/引用访问它,Base,但不能直接在Derived对象中访问,也不能通过引用/指针访问Derived.

// This should work:
Base *b = new Derived;
b->Display();

// and so should this:
Derived d;
Base &b = d;
b.Display();

...但是其中任何一个都需要公共继承以允许从Derivedto隐式转换Base

于 2013-09-30T17:05:19.450 回答
1

您不能在类之外调用具有私有继承的派生类方法,即使它被定义为公共,它也会变为私有。

于 2013-09-30T17:04:34.973 回答
0

私有继承对外部世界隐藏了每个方法和属性,因此Derived堆或堆栈上的实例不能像在主函数中那样直接调用 Display。您可以替换privatepublic以避免此类错误或使用指针Base来访问隐藏的基本方法。

编辑:根据 Jerry 的建议进行了改进。

于 2013-09-30T17:05:35.887 回答
0

私有继承创建一个“包含一个”关系(它实际上就像创建一个类型的成员变量Base)。您试图做的是创建一个“is-a”关系,这是通过公共继承完成的。

于 2013-09-30T17:07:51.797 回答