2013-02-24 35 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; 
}