【问题标题】:How to isolate a child with vector polymorphism如何隔离具有向量多态性的孩子
【发布时间】:2017-12-16 01:40:03
【问题描述】:
    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。

标签: c++ vector foreach polymorphism


【解决方案1】:

在这种情况下,您需要使用 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) { ... });

【讨论】:

    【解决方案2】:

    在使用多态性时,我倾向于在基类中使用枚举标识符。这样做的好处是您可以进行简单的整数比较以查看派生类型是否是该类型。不利的一面是,如果有人想添加另一个或新的派生类型,他们必须向基类枚举注册一个新的标识符。

    您的代码将如下所示:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-17
      • 1970-01-01
      • 2012-05-14
      • 1970-01-01
      • 2020-04-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多