简体   繁体   中英

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 .

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.

You have foo() in the private section of Grand_Son

The default access in a class in c++ is private , which has nothing to do with the way you inherit (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. 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.

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

Access is checked at the call point using the type of expression used to denote the object for which the memeber function is called. The access of the memeber function in the class in which it was defined is in general not know.

This means in your example, it will using Grand_Son to check the memeber accessbility. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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