C++:派生模板类和基类之间的向下转换和向上转换?

Posted

技术标签:

【中文标题】C++:派生模板类和基类之间的向下转换和向上转换?【英文标题】:C++: downcasting and upcasting between derived template class and base class? 【发布时间】:2016-11-05 14:10:25 【问题描述】:

我在将指向模板派生类的指针转换为基类指针以便存储在映射中时遇到了问题(显然稍后会检索它。)。我有:

#include <map>
//Role.h
class RoleBase;
enum class RoleEnum : int;

template<RoleEnum role>
class Role : public RoleBase;

//Relationship.h
class Relationship
public:
    template<RoleEnum role>
    Role<role>* getRole()
    auto it=RoleMap.find(role);
    if ( it == RoleMap.end() ) 
       return nullptr;
     else 
            RoleBase* roleBase= it->second;
            return static_cast<Role<role>* >(roleBase);
        
    
    std::map<RoleEnum,RoleBase*> RoleMap;
;

//squash.h
enum class RoleEnum : int

    Player,
    Referee
;

template<> class Role<RoleEnum::Player>;
template<> class Role<RoleEnum::Referee>;

class SquashGame: public Relationship
public:
    SquashGame()
        RoleBase* playerRole=new Role<RoleEnum::Player>; //problematic
        RoleMap.emplace(RoleEnum::Player,playerRole);
    
;

int main() 
    SquashGame squashGame;
    squashGame.getRole<RoleEnum::Player>();
    return 0;

为什么会这样?有没有办法解决这个问题,这样我就可以使用枚举值对一个类进行模板化,以便通过 getClass&lt;Enum&gt; 函数从外部调用,正如示例中所希望的那样?

【问题讨论】:

【参考方案1】:

问题很简单:你对角色的重新定义

template<> class Role<RoleEnum::Player> 

不扩展RoleBase

要么删除它,要么将其更改为:

template<> class Role<RoleEnum::Player> : public RoleBase 

【讨论】:

哈!为什么编译器没有警告我我不正确的模板专业化!猜猜编译器是如何解释这些角色的? 模板在你使用时被实例化,当模板被实例化时它是memoized。 如果你特化一个模板,编译器会使用你的定义而不是自己创建一个新的定义。

以上是关于C++:派生模板类和基类之间的向下转换和向上转换?的主要内容,如果未能解决你的问题,请参考以下文章

向上强制转换和向下强制转换

派生类和基类的转换

什么时候在 C++ 中向上转型是非法的?

C++入门派生类和基类的构造/析构函数关系

40-向下转换 as 定义接口

关于C++基类与派生类