2017-03-31 28 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; 
}