如何使用多态性从基类访问派生类向量成员?

Posted

技术标签:

【中文标题】如何使用多态性从基类访问派生类向量成员?【英文标题】:How to use polymorphism to access derived class vector member from base class? 【发布时间】:2014-12-25 06:46:39 【问题描述】:

据说通过多态性,我们可以像这样访问派生类成员字段及其基类对象:

#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;

结果出乎我的意料。我需要的是来自Person 的每个派生类都有一个向量tools,其中包含从Tool 类继承的对象。如果用单词描述,它会是,“这个Person,一个Programmer,有一些tools。他的第一个Tool是一个Computer。如果你想知道它是什么price,请使用getInfo()。”

    为什么vector采用基类而不是派生类? 当我将 cmp 对象放入 tools 向量中时,是否有任何数据丢失? 这是因为tools 向量成员将Tool 作为其类型吗?

【问题讨论】:

【参考方案1】:

C++ 中的运行时多态性通过虚函数实现,适用于covariant 类型。唯一的协变类型是指针和引用。因为你有一个vector&lt;Tool&gt;,所以你失去了多态性。要保留它,请存储 vector&lt;Tool*&gt;。更好的是,存储一个vector&lt;unique_ptr&lt;Tool&gt;&gt;

将派生类对象分配给基类称为object slicing。您确实会丢失派生对象中包含的信息。将Computer 插入vector&lt;Tool&gt; 时就是这种情况。

【讨论】:

这是否意味着,当Computer 对象存储到vector&lt;Tool&gt; 时,它变成Tool 对象?而Computer 对象丢失了它的price 值?

以上是关于如何使用多态性从基类访问派生类向量成员?的主要内容,如果未能解决你的问题,请参考以下文章

如何从基类向量中获取派生类变量?

如何通过派生类函数从基类更改向量

c ++设计:从基类转换为派生类,没有额外的数据成员

从基类派生类中 C++ 向量的可访问性

当有多个派生类时,如何使用基类指针访问派生类的函数成员?

从基类指针访问两个具有不同类型的派生成员变量。