获取具有基类函数的派生类

时间:2017-03-31 15:48:36

标签: c++ operator-overloading derived-class

我需要在类层次结构上对不同类型进行一些相等性检查。在伪代码中:

#include <string>
#include <memory>
#include <iostream>

using namespace std;

class ComplexType {};

class Property {};

class IntegerProperty : public Property {
public:
    int inner;
};

class StringProperty : public Property {
public:
    string inner;
};

class ComplexTypeProperty : public Property {
    ComplexType inner;
};


int main() {
    shared_ptr<Property> p1 = getSomewhere(); //this is in fact a pointer on IntegerProperty
    shared_ptr<Property> p2 = getSomewhere(); // this is in fact a pointer on StringProperty
    shared_ptr<Property> p3 = getSomewhere(); // this is in fact a pointer on CompleyTypeProperty

    ComplexType c;

    cout << ((*p1) == 2);
    cout << ((*p2) == "foo");
    cout << ((*p3) == c);
}

为派生类提供operator==很简单,但在检查之前我无法强制转换,因为p1p2的类型在编译时并不清楚。

我知道的另一种方法是在operator==基类中编写Property函数,如果类型错误则抛出一些异常,但我想,Property类可以是稍后进行子类化而不更改Property的代码,它也会起作用。

模板Property也不是(直接)可能的,因为例如在我的代码中,vector<shared_ptr<Property>>必须存在。

是否有一些(通用的)方法来实现main()以获得相等性检查,以便稍后对Property进行子类化而不更改类本身是可能的?

1 个答案:

答案 0 :(得分:0)

找到了解决这个问题的方法。我对代码不太满意。因此,如果有人有更好的解决方案,请提供。

#include <string>
#include <memory>
#include <iostream>

using namespace std;

class ComplexType {
public:
    bool operator==(const ComplexType& i) {
        return true;
    }
};
inline ostream& operator<<(ostream& os, const ComplexType& c) {
    os << "ComplexType";
    return os;
}

class Property {
public:
    virtual ~Property() {}
};

template <class T>
class LayerProperty : public Property {
private:
    T inner;

public:
    LayerProperty(T t) : inner(t) {}
    bool operator==(const T i) {
        return inner == i;
    }
};

int main() {
    shared_ptr<Property> p1 = make_shared<LayerProperty<int>>(LayerProperty<int>(5));
    shared_ptr<Property> p2 = make_shared<LayerProperty<string>>(LayerProperty<string>("foo"));
    shared_ptr<Property> p3 = make_shared<LayerProperty<ComplexType>>(LayerProperty<ComplexType>(ComplexType()));

    ComplexType c;

    cout << ((*dynamic_pointer_cast<LayerProperty<decltype(2)>>(p1)) == 2) << "\n";
    // special case std::string
    auto a = "foo";
    auto s = "";
    if (typeid(a) == typeid(s)) {
        cout << ((*dynamic_pointer_cast<LayerProperty<decltype(string(a))>>(p2)) == a) << "\n";
    }
    cout << ((*dynamic_pointer_cast<LayerProperty<decltype(c)>>(p3)) == c) << "\n";
    return 0;
}