简体   繁体   中英

C++ virtual class from base pointer?

#include <iostream>
using namespace std;

class Criminal {
public:
    virtual void getType() = 0;
    virtual void getCrime() { cout << "Unknown" << endl; }
};

class Thug : public Criminal {
public:
    void getType() { cout << "Thugging" << endl; }
    void getCrime() { cout << "Gangsterism" << endl; }
};

class Tupac : public Thug {
public:
    void getType() { cout << "Rapper" << endl; }
    void getCrime() {
        cout << "Being the best rapper to ever live" << endl;
    }
};

int main() {
    Criminal* tupac = new Tupac();
    Criminal* thug = new Thug();
    Thug* poser = new Tupac(); // Thug has no virtual function
    //Criminal shouldNotCompile;

    tupac->getType();       
    tupac->getCrime();      

    thug->getType();        
    thug->getCrime();       

    poser->getType();       // I intend to call Thug::getType()
    poser->getCrime();      // I intend to call Thug::getCrime()

    delete tupac;
    delete thug;
    delete poser;

    getchar();

    return 0;
}

The output is

Rapper
Being the best rapper to ever live
Thugging
Gangsterism
Rapper
Being the best rapper to ever live

But I intend the poser calls from the Thug pointer to print "Thugging" and "Gangsterism."

How can I do this? I expected my code to work as is, because the "Thug" functions are not virtual, so shouldn't anything called from a Thug* pointer call the Thug functions?

Why doesn't my code work the way I intended it to? Where is my confusion?

What is an easy way to get my intended behavior?

virtual -ness of member functions is inherited. You may not have declared Thug::getType() to be virtual , but it still is because Criminal::getType() is. Invoking getType() on any type whose object inherits from Criminal will still go through virtual dispatch. Unless, you explicitly specify which getType() you want:

poser->getType(); // virtual dispatch, ends up invoking Tupac::getType()
poser->Thug::getType(); // explicitly call Thug::getType(), no dispatch

These calls:

delete tupac;
delete thug;
delete poser;

are dangerous due to Criminal 's destructor not being virtual . You're not actually freeing all the memory or destroying all the members.

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