简体   繁体   中英

Implementation of a pure virtual function in C++

Given the following scenario, I have a base class MyBaseClass with a pure virtual function void foo() = 0; . Two classes MyClassA and MyClassB are derived from that class MyBaseClass . Both implement the function foo() . Now in a project I work on, I came across an object created from class MyBaseClass on which the function foo() is called. Interestingly, it's the implementation from MyClassB that is used. Where is defined that it's this implementation and not the one from MyClassA

The object was of type MyClassB not MyBaseClass . MyBaseClass is abstract and cannot be instantiated. However you probably had a pointer MyBaseClass* which was pointing to an instance of MyClassB .

You should probably read up on inheritance and polymorphism in C++ if you need some more information.

MyBaseClass base; // Compiler error, cannot instantiate abstract class
MyClassA a;
MyClassB b;

MyBaseClass* pA = &a;
MyBaseClass* pB = &b;

pA->foo(); // Uses implementation of foo in MyClassA
pB->foo(); // Uses implementation of foo in MyClassB

I came across an object created from class MyBaseClass

No, you did not. Objects of type MyBaseClass can't exist. The class is abstract and cannot be instantiated.

You likely came about a pointer to a MyBaseClass , which can point to any objects of classes that inherit the base class.

Is there a way of calling the implementation of MyClassA although pA is pointing to an object of class MyClassB? Maybe with a cast?

You can call

pA->MyBaseClass::foo();

but this will only work if the function is implemented. (yes, you can provide an implementation for pure method)

It is important to notice the difference between these snippets:

struct X
{
    virtual void foo() = 0;
};

X x; // not valid! X has purely virtual methods

and

struct X; // as above
struct Y : X
{
    void foo() {}
    void bar() {}
};

X * x = new Y; // valid! 

The second case is most likely what you have seen. In this pattern you can call x->foo(); and it will call Y::foo() . Note that you cannot, however, call x->bar() because X::bar() does not exist.

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