简体   繁体   English

多级继承和纯虚函数

[英]Multilevel Inheritance and Pure Virtual Functions

A class containing a pure virtual function can not have an object. 包含纯虚函数的类不能包含对象。 That was my idea about pure virtual functions. 这是我对纯虚函数的看法。 I have the following program and it compiled without any error. 我有以下程序,它编译没有任何错误。

#include<iostream>

using namespace std;

class Father {
   public:
   virtual void foo()=0;
};

class Son:public Father {
  // Nothing here 
};

int main() {

}

This was expected as both the classes does not have an object. 这是预期的,因为这两个类都没有对象。 But the following program gave me errors when I tried to have multilevel inheritance off a class containing a pure virtual function. 但是当我试图从包含纯虚函数的类中获得多级继承时,下面的程序给了我错误。

#include<iostream>

using namespace std;

class Father {
   public:
   virtual void foo()=0;
};

class Son:public Father {
  // Nothing here
};

class Grand_Son:public Son {
    void foo() {
        cout<<"\nFunction foo From Grand_Son\n";
    }
};

int main() {
   Grand_Son x;
   x.foo();
}

The errors are shown below. 错误如下所示。

In function 'int main()':|
|error: 'virtual void Grand_Son::foo()' is private|
|error: within this context|
||=== Build finished: 2 errors, 0 warnings ===|

The errors were unexpected as I have inherited the classes Son and Grand_Son as public . 因为我继承的类的错误是意想不到的SonGrand_Sonpublic

Is it possible to have multilevel inheritance with classes involving pure virtual functions? 是否可以使用涉及纯虚函数的类进行多级继承?

Any suggestions? 有什么建议么? Thank You. 谢谢。

class Grand_Son:public Son {
   public:
---^^^^^^^
    void foo() {
        cout<<"\nFunction foo From Grand_Son\n";
    }
};

You haven't declared foo public - I added it above. 你没有宣布foo公开 - 我在上面添加了它。

You have foo() in the private section of Grand_Son 你在Grand_Son的私人部分有foo()

The default access in a class in c++ is private , which has nothing to do with the way you inherit (public/private/protected/default). c ++中class的默认访问权限是private ,这与您继承的方式无关(public / private / protected / default)。

Not only that but you aren't actually using any traits of inheritance of this example as you are using a concrete child class here, so it has nothing to do with it being virtual. 不仅如此,你实际上并没有使用这个例子的任何继承特性,因为你在这里使用一个具体的子类,所以它与虚拟无关。

class Grand_Son:public Son {
    public: <------- This will fix your compiler problem.
    void foo() {
        cout<<"\nFunction foo From Grand_Son\n";
    }
};

OR this should work, because you will be using the class polymorphically on the base class, which will do a v-table lookup based on the access level in the base class. 或者这应该有效,因为您将在基类上以多态方式使用该类,它将根据基类中的访问级别执行v表查找。 You should be consistent with your access levels though throughout the hierarchy. 您应该在整个层次结构中与您的访问级别保持一致。

int main() {
   Father* x = new Grand_Son();
   x->foo();
}

您需要在Grand_Son中将您的foo()实现声明为public

This is completely unrelated. 这完全不相关。 You must declare your foo() function in your Grand_Son class after a public: statement. 您必须在public:语句之后在Grand_Son类中声明您的foo()函数。

By default (ie without visibility qualifiers), class members are private, thus your compiler telling you that you can't access the member function because it has private visibility. 默认情况下(即没有可见性限定符),类成员是私有的,因此编译器会告诉您无法访问成员函数,因为它具有私有可见性。

Base on the standard class.access.virt 基于标准class.access.virt

Access is checked at the call point using the type of expression used to denote the object for which the memeber function is called. 使用用于表示调用memeber函数的对象的表达式类型在调用点检查访问。 The access of the memeber function in the class in which it was defined is in general not know. 通常不知道在定义它的类中访问memeber函数。

This means in your example, it will using Grand_Son to check the memeber accessbility. 这意味着在您的示例中,它将使用Grand_Son来检查memeber可访问性。 As you didn't define the member as public so it will be private (class member by default is private). 由于您没有将该成员定义为公共成员,因此它将是私有的(默认情况下,类成员是私有的)。 It doesn't have relationship with the public inheritation. 它与公共继承没有关系。

And define the override virtual function as private is also useful for design purpose. 并将覆盖虚拟函数定义为私有对于设计目的也很有用。 Think about you have an interface which has public virtual function which need to be override. 想想你有一个具有公共虚拟功能的接口需要覆盖。 You can force the caller using interface instead of the concrete type, by implement the derived class memeber function as private. 您可以通过将派生类memeber函数实现为private来强制调用者使用接口而不是具体类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM