2017-03-31 62 views
0

我需要在类层次结构中使用不同类型执行一些相等性检查。在伪代码:获取具有基类函数的派生类

#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类型是在编译时明确。

我知道另一种方式是写在Property基类operator==功能,并抛出一些例外情况,如果该类型是错误的,但我想,那Property级以后可以在不改变代码Property子类,它会工作也是如此。

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

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

+0

如果我已经理解了您要求的正确内容,则应该在网上搜索* double dispatch *。 – BoBTFish

+0

@BoBTFish:如果我得到_double dispatch_权限,这可以与ComplexType一起使用,但不能与Integer,String ...一起使用,因为它们不共享公共超类。 – gerion

+0

也许运营商==与std :: variant或任何?只是抛出想法... –

回答

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