简体   繁体   中英

How to use polymorphism to access derived class vector member from base class?

It's said that with polymorphism, we can access a derived class member field with it's base class object like this:

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

using namespace std;

class Tool{
    public:
        Tool(){}
        Tool(string name){
            this->name = name;
        }
        virtual string getInfo(){
            return name;
        }
    //protected:
        string name;
};

class Computer: public Tool{
    public:
        Computer(string name, int price){
            this->name = name;
            this->price = price;
        }
        virtual string getInfo(){
            return name + ": " + to_string(static_cast<long long>(price));
        }
    //protected:
        int price;
};

class Person{
    public:
        Person(){}
        Person(string name){
            this->name = name;
        }
        virtual string getInfo(){
            return name;
        }
        virtual void addTools(Computer cmp){
            tools.push_back(cmp);
        }
    //protected:
        vector<Tool> tools;
        string name;
};

class Programmer: public Person{
    public:
        Programmer(string name, string job){
            this->name = name;
            this->job = job;
        }
        string getInfo(){
            return name + ": " + job;
        }
    //protected:
        string job;
};

int main(){
    Person prs("Person");
    Programmer prg("Daphloon", "programmer");

    Person* prs1 = &prs;
    Person* prs2 = &prg;

    cout << prs1->getInfo() << endl;    // result: Person
    cout << prs2->getInfo() << endl;    // result: Daphoon: programmer

    Tool tl("Hammer");
    Computer cmp("PC", 100);

    Tool* tl1 = &tl;
    Tool* tl2 = &cmp;


    cout << tl1->getInfo() << endl;     // result: Hammer
    cout << tl2->getInfo() << endl;     // result: PC: 100

    prs2->addTools(cmp);

    cout << prs2->tools[0].getInfo() << endl;   // result: PC
                                                // I expect the result will be: PC: 100 

    return 0;
}

The result wasn't what I expected. What I need is every derived class from Person have a vector tools that contains object that inherit from Tool class. If it described with word, it will be, "This Person , a Programmer , has some tools . His first Tool is a Computer . If you want to know what's it's price , use getInfo() ."

  1. Why vector take the base class instead of the derived class?
  2. Is there any data loss from cmp object when i put it inside tools vector?
  3. Is this happen because tools vector member take Tool as it's type?

Runtime polymorphism in C++, achieved via virtual functions, works on covariant types. The only covariant types are pointers and references. Since you have a vector<Tool> , you lose polymorphism. To retain it, store a vector<Tool*> . Even better, store a vector<unique_ptr<Tool>> .

Assigning a derived class object to a base class is called object slicing . You do lose information contained in the derived object. This is the case when you are inserting a Computer into a vector<Tool> .

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