2013-02-24 63 views
1

在C++動態轉換,我想能夠做到以下幾點:從封裝接口

struct IWrapper { 
    template<typename U> 
    U* dynamic_cast_to() { ??? } // what to do here? 
}; 

template<typename T> 
struct Wrapper : IWrapper { 
    Wrapper(T* _p) :p(_p) {}  
    T* p; 
}; 

有了這個,我希望能夠做到

SomeDerived *a = new SomeDerived; 
IWrapper *x = new Wrapper<SomeDerived>(a); 
SomeBase *b = x->dynamic_cast_to<SomeBase>() 

dynamic_cast_to()應該返回一個指針,如果確實SomeDerived繼承SomeBaseNULL,如果不是,正常dynamic_cast的工作方式相同。

這甚至可能嗎?

回答

1

IWrapper虛擬析構函數並使用dynamic_cast

我很驚訝,問題是如何實現dynamic_cast_to功能。

如何能一避免考慮標準dynamic_cast呢?

+1

這將無法正常工作。能夠將'dynamic_cast'' SomeDerived'轉換爲'SomeBase'並不意味着您可以''包裝器''轉換爲'包裝器'。這就是整個問題。 – shoosh 2013-02-24 17:35:46

+2

您要求將'Wrapper '轉換爲'SomeBase',而不是'包裝'。你是什​​麼意思? – Useless 2013-02-24 17:43:54

+0

嘿2個贊成票是什麼?任何downvoter照顧解釋?他們在我看來很不合適。 – 2013-02-24 20:09:10

1

我不認爲這可以爲任意類型的T和U.做的原因是, 編譯器生成用於對特定的類型在編譯時dynamic_cast的代碼, 並沒有什麼地方這兩種類型在編譯時同時知道。

如果你能限制IWrapper只是從一定基礎,有虛成員函數派生類型的工作,那麼它可能像這樣工作:

struct IWrapper { 
    template<typename U> 
    U* dynamic_cast_to() { return dynamic_cast<U*>(commonBasePtr()); } 

    virtual CommonBase* commonBasePtr() = 0; 
}; 

template<typename T> 
struct Wrapper : IWrapper { 
    Wrapper(T* _p) :p(_p) {}  
    T* p; 

    virtual CommonBase* commonBasePtr() { return p; } 
}; 
0

不可能那樣的,因爲IWrapper不知道T的任何事情,也不能訪問指針。這應該工作:

template <typename T> 
struct IWrapper { 
    IWrapper(T* p) : p_(p) {} 
    template<typename U> 
    U* dynamic_cast_to() { return dynamic_cast<U*>(p_); } 
private: 
    T* p_; 
}; 

template<typename T> 
struct Wrapper : IWrapper<T> { 
    Wrapper(T* _p) : IWrapper<T>(_p), p(_p) {}  
    T* p; 
}; 

struct SomeBase { 
    int a; 
}; 

struct SomeDerived : public SomeBase { 
    int b; 
}; 

int main() 
{ 
    SomeDerived *a = new SomeDerived; 
    IWrapper<SomeDerived> *x = new Wrapper<SomeDerived>(a); 
    SomeBase *b = x->dynamic_cast_to<SomeBase>(); 
    return b->a; 
}