子类继承的非公共虚函数会发生什么情况

what happens for virtual function that is non-public inherited by subclass?

本文关键字:函数 什么情况 继承 子类      更新时间:2023-10-16

>我 http://www.careercup.com/question?id=384062 看到过这个问题

class Base {
public :
    virtual void method () = 0;
private :
    int n;
};
void Base::method() { n = 1;}
class D1 : Base {};
class D2 : public D1 {
    int i;
    void method() {i = 2;}
};

它通过了 vs2008 和 g++ 4.4.3 的编译器

这是我对以上代码的理解,如果我错了,请纠正我

S1> D1 继承了变量 Base::n,但它无法访问它。

S2> D1 继承了函数 Base::method,但它不会在上面的实现中调用/修改这个继承的函数。

S3> D2::方法 不是 D1::method 的重写版本

S2 和 S3 是错误的。

D1 的方法可以调用它的 Base::method((,但其他代码不能,因为 D1 的 Base 部分是私有的。

Base::method(( 被 D2 覆盖。如果您以某种方式将 (new D2( 转换为 (Base*( 并调用 Base::method,则 i=2 代码将运行。

考虑到访问控制,如果你有指向 Base* 的指针,外部代码可以使用 ->method((,因为它是公共的,如果你有指向 D2* 的指针,则不能调用 ->method((,因为它是私有的,即使它是相同的对象和相同的方法。

此外,尽管你为 Base::method(( 实现了 (n=1(,但它和它的类仍然是抽象的。

D1

继承了变量Base::n但无法访问它。
正确。
除同一类的成员外,永远无法从任何位置访问类的私有成员。


D1继承了Base::method函数,但它不会在上面的实现中调用/修改此继承的函数。
正确,但从本质上讲,请阅读以下内容以了解原因:

D1继承Base::method但它不会调用/调用它,因为您没有添加任何语句来执行此操作。但它可以称之为。
纯虚函数可以有一个主体,它们可以像任何其他成员函数一样由驱动类成员调用。

class D1 : Base 
{
    public:
        void doSomething()
        {
            Base::method();
        }
}; 

请注意,在你的基类中,n是私有的,所以访问它的唯一方法是通过 Base 的成员函数,因为只有method()可以这样做,所以你可以通过它来完成。

请注意,至少存在一个纯虚函数会使类成为抽象类,并且不能创建抽象类的对象。从抽象类派生的任何类都必须覆盖基类的所有纯虚函数,否则派生类也将成为抽象类。

基于上述规则,
在您的情况下,BaseD1都是抽象类。


D2::method不是D1::method
的覆盖版本不對
虽然method()不能通过类D1的实例进入世界,但它仍然是其中的一部分。访问控制规定访问权限,而不是成员的存在与否。
所以,是的,D2::methodD1::method覆盖版本,它也隐藏了它,只是在这种情况下,D1::method首先是不可接受的

在这种情况下,Base 类和 D1 类都是无法实例化的抽象类。

S1 - 是

S2 - 是 D1 继承了该函数。你能澄清你的问题吗?

S3 - 编号 D2::方法是您为 D2 类提供的覆盖。

编辑:我刚刚注意到D1Base班的私人继承。在这种情况下,S1 和 S2 仍然有效。

更新:S3:D2::方法覆盖和隐藏基类方法。

S1:正确

S2:正确

S3:正确,更清楚地 D2::方法隐藏 D1::方法

S1 - 正确

S2 - 对不起,我不太清楚你的意思。在D1或子类中,您可以定义method()以在Base中覆盖它,但不能调用它。而且,由于私人继承,D1*无法转换为Base*

S3 - 不正确。一旦您将成员函数声明为基类中的virtual,即使您省略virtual,它也会将virtual保留在子类中。因此,在您的情况下,D2中的method()D1::method()Base::method()的覆盖版本。

相关文章: