与抽象基类的智能指针向量的容器类

时间:2014-08-22 21:11:31

标签: c++ stl

我在创建容器类时遇到了一些问题。

这是我想要的行为:

class AbstractBase
{
    public:
        AbstractBase() { }
        virtual std::string toString()=0;
};


class Derived : public AbstractBase
{
    public:
        Derived() { }
        std::string toString() { return "Just an example " + std::to_string( _value ); }
    private:
        int _value;
};

void Container::print()
{
    for( auto i : bunch_of_different_derived_objects_that_i_own )
        std::cout << i.toString() << std::endl;
}

通过仅保留指向AbstractBase类的指针来创建“拥有”一堆不同派生对象的容器类的最佳方法是什么?

是否可以在不知道其定义的情况下使容器类拥有不同的派生对象?

使用

std::vector<std::shared_ptr<AbstractBase>> 

导致奇怪的行为和

std::vector<std::unique_ptr<AbstractBase>> 

无法迭代。

有可能实现我想要的目标吗?

2 个答案:

答案 0 :(得分:5)

<强> 1。声明虚拟析构函数

class AbstractBase
{
public:
    AbstractBase() { }
    virtual ~AbstractBase() = default; // this is (defaulted) virtual destructor
    virtual std::string toString() = 0;
};

class Derived : public AbstractBase
{
public:
    Derived() { }
    virtual std::string toString() override { return "Just an example " + std::to_string( _value ); }
private:
    int _value;
};

<强> 2。将shared_ptr存储在向量中

std::vector<std::shared_ptr<AbstractBase>> v = { std::make_shared<Derived>() };

第3。做你的东西而不再关心析构函数。

for (auto i : v)
{
    std::cout << i->toString() << std::endl;
}

答案 1 :(得分:0)

问题似乎是构建for()循环:

for (auto i : bunch_of_different_derived_objects_that_i_own)
{
    i.toString();
}

auto推断出类型为std::shared_ptr。您不能使用.运算符来调用成员函数,因为这将查找专门属于std::shared_ptr类的成员函数。使用间接运算符->,以便可以访问指向类型的成员函数:

i->toString();

使用std::unique_ptr将无效,因为auto类型扣除规则等同于按值推断其类型的函数模板。按值绑定到参数将导致移动或复制,具体取决于参数的值类别。由于向量的元素是左值,因此只能移动std::unique_ptr s(因此名称​​ unique ),因此无法执行复制。

使用引用来阻止复制:

for (auto& i : bunch_of_different_derived_objects_that_i_own)

您还需要一个基类的虚拟析构函数。如果你不提供一个,你的元素的基类子对象将被调用,而不是派生的部分。