简体   繁体   中英

Function that takes a base class pointer in C++ that is overloaded with a pointer to a subclass

This is the example code I have:

#include <iostream>
#include <vector>
#include <string>

class Animal {

};

class Rabbit : public Animal {

};

class Caller {
    public:
    virtual void call(Animal* a) {
        std::cout << "Caller calls animal" << std::endl;
    }

    virtual void call(Rabbit* r) {
        std::cout << "Caller calls rabbit" << std::endl;
    }
};


int main(int argc, char** argv) {
    std::vector<Animal*> v;
    Caller c;
    auto a = new Animal();
    auto r = new Rabbit();
    v.push_back(a);
    v.push_back(r);


    for(auto elem : v) {
        c.call(elem);
    }


    return 0;
}

The output of this code can be found here

http://ideone.com/I29g3A

and it outputs:

Caller calls animal
Caller calls animal

I'm wondering, without casting a specific element to Rabbit* , is there a way to get call(Rabbit *r) method to get called?

Sure, eg, by jumping through a suitable visitor in your system of polymorphic classes. I think you'll need to use two names instead of call() , however. I used pubCall() and call() .

#include <iostream>
#include <vector>
#include <string>

class Visitor;

class Animal {
public:
    virtual void visit(Visitor&);
};

class Rabbit : public Animal {
    void visit(Visitor&);
};

class Visitor
{
public:
    virtual void call(Animal* a) = 0;
    virtual void call(Rabbit* r) = 0;
};

void Animal::visit(Visitor& v) {
    v.call(this);
}

void Rabbit::visit(Visitor& v) {
    v.call(this);
}

class Caller
    : Visitor {
public:
    void pubCall(Animal* a) { a->visit(*this); }

private:
    virtual void call(Animal* a) {
        std::cout << "Caller calls animal" << std::endl;
    }

    virtual void call(Rabbit* r) {
        std::cout << "Caller calls rabbit" << std::endl;
    }
};


int main(int argc, char** argv) {
    std::vector<Animal*> v;
    Caller c;
    auto a = new Animal();
    auto r = new Rabbit();
    v.push_back(a);
    v.push_back(r);


    for(auto elem : v) {
        c.pubCall(elem);
    }


    return 0;
}

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