如何与载体多态性分离儿童

How to isolate a child with vector polymorphism

本文关键字:分离 多态性      更新时间:2023-10-16
    class problem
{
public:
virtual void show() =0;
}
class wound : public problem
{
public:
void show();
}
class disease: public problem
{
public:
void show();
}
vector<problem*> lstProb;
// I want to show all wounds only, no diseases yet
for each (wound* ouch in  lstProb)
   ouch->show();
// Here only the diseases
for each (disease* berk in  lstProb)
   berk->show();

我的问题是,在"每个"上,所有问题都列出了。有没有办法做到这一点?我不想添加一个标识子类的变量。

在这种情况下,您需要使用dynamic_cast,因为您无法保证在向量中具有的派生类型。

类似的事情有效:

template <class DerivedType, class BaseType, class F>
void for_each(vector<BaseType *> elems, F && f) {
    for (auto elem : elems)
        if (auto ptr = dynamic_cast<DerivedType*>(elem))
            f(elem);
}
//usage
for_each<Wound>(allelems, [](Wound * w) { ... });
for_each<Disease>(allelems, [](Disease * d) { ... });

使用多态性时,我倾向于在基类中使用枚举标识符。Pro是您可以进行简单的整数比较,以查看派生类型是否为该类型。骗局是,如果某人想添加其他派生类型,则必须将新标识符注册到基础类枚举。

您的代码将看起来像这样:

class Problem {
public:
    enum Type {
        WOUND,
        DISEASE
    };  
protected:
    Type type_;
public:
    virtual void show() = 0;
    Type getType() const {
        return type_;
    } 
protected:
    explicit Problem( Type type ) : type_( type ) {}
};
class Wound : public Problem {
public:
    static unsigned counter_;
    unsigned id_;
    Wound() : Problem( Type::WOUND ) {
        counter_++;
        id_ = counter_;
    }
    void show() override {
        std::cout << "Wound " << id_ << "n";
    }
};
unsigned Wound::counter_ = 0;

class Disease : public Problem {
public:
    static unsigned counter_;
    unsigned id_;
    Disease() : Problem( Type::DISEASE ) {
        counter_++;
        id_ = counter_;
    }
    void show() override {
        std::cout << "Disease " << id_ << "n";
    }
};
unsigned Disease::counter_ = 0;
int main() {
    std::vector<Problem*> Probs;
    // Add 10 of each to the list: types should be alternated here
    // Vector<Problem> should look like: { wound, diesease, wound, disease...}
    for ( unsigned i = 0; i < 10; i++ ) {
        //Wound* pWound = nullptr;
        //Disease* pDisease = nullptr;
        Probs.push_back( new Wound );
        Probs.push_back( new Disease );
    }
    for (auto ouch : Probs) {
        if ( ouch->getType() == Problem::WOUND ) {
            ouch->show();
        }
    }
    std::cout << "n";
    for (auto berk : Probs) {
        if ( berk->getType() == Problem::DISEASE ) {
            berk->show();
        }
    }
    // clean up memory
    for each (Problem* p in Probs) {
        delete p;
    }
    std::cout << "nPress any key and enter to quit." << std::endl;
    char c;
    std::cin >> c;
    return 0;
}