使用多态性是在一个容器下存储不同数据类型的好方法吗?

Posted

技术标签:

【中文标题】使用多态性是在一个容器下存储不同数据类型的好方法吗?【英文标题】:Is using polymorphism a good way to store different datatypes under one container? 【发布时间】:2016-10-27 22:09:31 【问题描述】:

一个例子是创建一个基类,它有几个派生类,它们都有不同的数据类型与之关联。例如,int、double 和另一个类的对象。

如果每个派生类都有自己的数据类型,我是否能够通用地使用基类,这样我就可以在只命名基类的同时与所有派生类对话。

我的计划是存储类的内存位置并启动它们并将它们全部存储在一个自定义容器中。 (我要重新创建一个Map容器​​来学习)

一旦存储为地址,我是否需要明确说明内存位置数量,或者编译器会在派生类时知道。

不使用任何第三方工具。

【问题讨论】:

你可以使用 boost::any 或 boost::variant 来做那种事情。如果我是你,我会,而不是自己做。顺便说一句,“变体”是您要查找的关键字。 是的,只要您将指针存储在容器中,您就可以这样做。否则你会遇到切片问题 @MarkRansom 我是否必须明确说明指针的大小,或者编译器是否会增大大小以免丢失信息。您知道任何可以帮助我解决此问题的文档吗? 当您使用new 创建指针时,它将为您指定给new 的类类型使用适当的内存量。如果要删除指针而不首先将它们转换为正确的类型,则还需要在基类上使用虚拟析构函数。 指针大小相同:正好是一个地址。指针指向的可以是任意大小。建议在继续之前先玩一下并了解指针。如果您已将析构函数定义为virtual,则运行时将能够计算出大小并正确删除。 【参考方案1】:

这取决于。如果您只想使用多态性来将数据存储在一个容器中,那不是一个好主意。正如 Robinson 在评论提升中提到的那样,可以帮助您(boost::anyboost::variant)。随着即将推出的 c++17 标准,您将可以在 std 命名空间中使用它们:std::anystd::variant

【讨论】:

我不想使用任何第三方库。如果我想在没有任何其他库的情况下这样做,你会建议什么? 嗯...我不知道你为什么不想使用 boost,但这是你的选择 :) 。您可以制作自己的 any 实现。网上应该有一些实现的例子。【参考方案2】:

是的,多态性可能是一种选择,只要您可以设置所有对象通用的 api。正如马克所说,你应该处理指针,或者更好的智能指针;对象大小将通过这种方式自动管理。

以下代码说明了如何为多种类型实现容器。容器(一个向量)存储智能指针,每个指针指向一个动态分配的对象,并且每个指针都有一个恒定的大小(无论对象指向的大小是多少)。

class Base 
    public:
    virtual ~Base() 
    virtual void work(int) = 0;
;
class A : public Base 
    void work(int i) std::cout << "A:" << i << std::endl; 
;
class B : public Base 
    void work(int i) std::cout << "B:" << i << std::endl; 
;

int main() 
    std::vector<std::shared_ptr<Base>> db;
    db.push_back(std::make_shared<A>());
    db.push_back(std::make_shared<B>());
    db[0]->work(0);
    db[1]->work(1);
    return 0;

输出:

A:0
B:1

【讨论】:

以上是关于使用多态性是在一个容器下存储不同数据类型的好方法吗?的主要内容,如果未能解决你的问题,请参考以下文章

什么是多态性

什么是多态性

什么是多态?

多态你真的了解吗?

java中重载,继承,重写和多态的区别

面向对象之多态