如何使用Smart-Pointers和Subclasses

时间:2016-12-15 22:46:40

标签: c++ c++11 stl

我第一次看了智能指针,并尝试将其应用于多态。

让我们想到一个父类Auto和子类Van,Estate,Convertible,....

我有一个元素类型Auto列表。我将子类的对象插入其中。

std::list <Auto *> lst;
lst.push_back (new Van ());

如果我把它弄出来,如果做一个类型检查以不同的方式处理它。

带有原始指针的旧代码。

 Auto *a = list.first ();  // returns Auto*
 if (typeid (*a) == typeid (Van))  
 { // do van things }
 ...

这很有效。

但如果我在每个级别切换到shared_ptrs都不行。

std::shared_ptr <Auto> a = list.first ()

typeid始终是Auto的shared_ptr。我期望子类的shared_ptr。

如果我使用smart-ptr的核心来实现它。

Auto *p = a.get ();
typeid (*p)  // is Van if it is a Van

但我相信这不是最优雅的方式。怎么做呢?智能指针??

编辑:

我需要

  • 所有类型的汽车都有1个列表

  • 如果我把它单独处理掉。

编辑:

我用子类替换多态。 因为它不是关于向对象发送消息而是关于它的类型执行,而是关于外部的类型检查。

感谢您的帮助,chis

1 个答案:

答案 0 :(得分:4)

使用dynamic_cast,绝不使用typeid

if (Van* item = dynamic_cast<Van*>(a)) {
    item->doVanThings(); // do van things 
} //else try other casts

更好的方法是让多态分化,因为你已经使用过多态:

class Auto {
public:
    virtual void doThings() = 0;
};

class Van : public Auto {
public:
    void doThings() override {
        // do van things
    }
};

class Estate : public Auto {
public:
    void doThings() override {
        // do estate things
    }
};

class Convertible : public Auto {
public:
    void doThings() override {
        // do convertible things
    }
};

std::list<Auto *> lst;
...
Auto *a = lst.first();
a->doThings();

std::list<std::shared_ptr<Auto>> lst;
...
std::shared_ptr<Auto> a = lst.first();
a->doThings();