Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.3k views
in Technique[技术] by (71.8m points)

c++ - 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?
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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>.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...