Distinc派生类C ++

时间:2017-03-23 07:46:47

标签: c++ design-patterns

我有一个基类和两个派生类。现在我想创建一个基类向量。当我添加新元素时,它会检查新元素的哪个类。但是在C ++中,没有像instanceOf这样的函数,所以我必须添加变量type来检查。这是我的一段代码。

class Element {
public:
    int type;
    int getIndex() const {
        return index;
    }

    void setIndex(int index) {
        this->index = index;
    }

    const std::string& getMsg() const {
        return msg;
    }

    void setMsg(const std::string& msg) {
        this->msg = msg;
    }

    std::string toString() {
        std::stringstream sbuf;
        sbuf << "index: " << index << "\n";
        sbuf << "Message: " << msg << "\n";
        return sbuf.str();
    }

private:
    int index;

    std::string msg;

};

两个派生类:

class This: public Element {
public:
    This():Element(1){}
    ~This();

    const std::vector<std::string>& getArguments() const {
        return arguments;
    }

    void setArguments(const std::vector<std::string>& arguments) {
        this->arguments = arguments;
    }

    void add(std::string value) {
        arguments.push_back(value);
    }

private:
    std::vector<std::string> arguments;


};

class That: public Element {
public:
    That():Element(2){}
    ~That();

    const std::string& getThatVal() const {
        return thatVal;
    }

    void setThatVal(const std::string& thatVal) {
        this->thatVal = thatVal;
    }

private:
    std::string thatVal;


};

在另一个类中,我想创建Element的数组。

class Visitor {
private:
    int numOfThis = 0;
    int numOfThat = 0;
    std::vector<Element> vecEle;

public:
    void add(Element ele) {
        vecEle.push_back(ele);
        if (ele.type == 1) {
            numOfThis++;
        } else if (ele.type == 2) {
            numOfThat++;
        }
    }

    int getNumOfThat() const {
        return numOfThat;
    }

    int getNumOfThis() const {
        return numOfThis;
    }
};

我的问题是如何更好地处理这个问题?这种情况有设计模式吗?感谢

2 个答案:

答案 0 :(得分:4)

您可以在向量中存储指针而不是对象,如:

std::vector<Element *> vecEle;

然后,您可以使用dynamic_cast来确定哪个派生类是指针的类型。

// dynamic_cast will try to convert pointer of base class to derived class, 
// and return NULL on fail
Element *pElem= vecEle[0]; // you can traverse your vector if needed
if (This *pThis = dynamic_cast<This *>(pElem)) {
    // object is This type
} else if (That *pThat = dynamic_cast<That *>(pElem)) {
    // object is That type
}

答案 1 :(得分:1)

Class Element应该是一个包含名为的纯虚函数的基类 即 VisitElement( Visitor* visitor)

类Visitor与您在代码中描述的类无关,它实际上是作为名为Visitor的设计模式实现的。这意味着它包含重载函数

void Visit(This* thisElem) {thisElem->VisitElement(this)}

void Visit(That* thatElem){thatElem->VisitElement(this)}

此访问者类还将包含int counterThisint counterThat。在类中这对于VisitElement的实现就像

一样简单

VisitElement( Visitor* visitor){ visitor->counterThis++;}

在课堂上,VisitElemnt的实现就像

一样简单

VisitElement (Visitor* visitor){ visitor->counterThat++;}

最后为了实际计算,你需要遍历基类Element指针的向量以及向量调用visitor->Visit(elemFromBector)中包含的每个指针。循环完成后,您可以查询访问者对象以获取所需的两个整数。 请记住,此解决方案涉及多态性和访问者设计模式以及您在原始代码中似乎遗漏的一些封装原则。

不要使用dynamic_cast它是不合适的,它不应该在任何生产代码中。如果您认为需要dynamic_cast再考虑一下,因为您的代码出了问题。 有关多态封装访问者设计模式的最佳建议,您应该能够非常轻松地理解我的逻辑。