c++ - 有关模板和虚拟功能的问题

标签 c++ templates inheritance virtual-functions

我的模板有问题-虚拟功能不匹配。

首先,我有一个名为Unit的父类。
和2个子类HeroMonster
这两个类都有两个子类,Hero的子类之一是Crusader

class Unit {
  template <typename target>
  virtual void  Attack(typename std::vector<target>::iterator targetPtr, std::shared_ptr<AttackSkill> skillPtr) {} 
  //ERROR (template function can not be virtual)
};

class Hero : public Unit {
  template <typename target>
  virtual void  Attack(typename std::vector<target>::iterator targetPtr, std::shared_ptr<AttackSkill> skillPtr) {}
  // ERROR (template function can not be virtual)
};

class Crusader : public Hero {
  template <typename target>
  void Attack(std::vector<target>::iterator targetPtr, std::shared_ptr<AttackSkill> skillPtr) {}
};


// Unit vector that contains heroes and monsters 
std::vector<Unit> unitVector;

Crusader crusader1; 
unitVector.at(0).emplace_back[crusader1];

问题是,我想通过将Attack函数写入unitVector[0]类和virtual void Attack类来从Hero访问Unit函数
但不幸的是,C++不允许这样做。
我应该怎么写这些虚函数?
或者我可以使用一些通用指针(如果有这样的东西)来代替模板吗?

我想使用来自不同怪物和英雄的攻击功能,所以我必须使用模板。如果我尝试编写不同的函数,例如attackHeroattackMonster,则其中之一将不起作用,因为当我这样做时,我基本上是在尝试采用某些不存在的类的 vector 的迭代器。

请帮帮我!

最佳答案

模板不是您这里需要的工具。是多态的。

当您具有必须处理多个不相关类型的相似或相同代码时,模板很有用。当您拥有一组都需要做不同事情的直接相关类型时,多态性很有用。

在这里,您有十字军,英雄和怪兽,它们全部以不同的方式攻击并受到伤害并移动,但它们也都是不同的单位,这意味着它们都是直接相关的,属于第二类。

现在,理论很好,但是我们更关注实现而不是理论……

要解决该问题,您需要执行两个修复。

首先,类定义与编写的是不正确的-我们不需要任何模板内容,因此可以消除所有这些东西。

class Unit
{
public:
    Unit();
    virtual ~Unit();

    virtual void Attack(std::shared_ptr<Unit> Target, const AttackSkill& skill);

};

...

class Hero : public Unit
{
public:
    Hero();
    virtual ~Hero();

    virtual void Attack(std::shared_ptr<Unit> Target, const AttackSkill& Skill) override;

};

...

class Crusader : public Hero
{
public:
    Crusader();
    ~Crusader();

    void Attack(std::shared_ptr<Unit> Target, const AttackSkill& Skill);

};


在这里,我假设Crusader没有任何子类-如果有,请确保析构函数和Attack()都是虚拟的。

现在,第二个主要更改是您的收集和插入方法:

std::vector<std::shared_ptr<Unit>> Units;

...

Units.emplace_back(std::make_shared(new Crusader());


这里的主要区别是使用指针。 C++中的多态性基本上要求您使用指针-使用没有指针的纯对象将导致编译器“ slice ”您的类,从而删除任何自定义行为。例如,如果您添加一个圣洁修饰符作为Crusader类的成员,然后尝试从“ slice ”类访问该修饰符,则这将成为一个主要问题-该程序将立即崩溃,因为“ slice ”会删除基类中没有的任何内容从对象。

为了使它们更“小巧”,我将指针包装在std::shared_ptr中。当没有更多引用时,这将提供自动引用计数和销毁。但是,无论您使用std::shared_ptr还是原始指针,都适用相同的规则。

关于c++ - 有关模板和虚拟功能的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61665963/

相关文章:

c++\"转义序列用于在 system() 函数中包含引号

iphone - Box2d Loop Shape/在 Cocos2D 中创建静态地面形状

c++ - 如何约束模板化 constexpr 递归函数输入参数

java - 在 FreeMarker 中发出错误信号

java - 在子类中实现 clone()

c++ - Arduino LCD仅显示第1行的前16个字符和第2行的41到46个字符

c++ - 二进制 == : no operator found which takes a left hand operand; vector; iterator

c++ - 使用静态方法(又名工厂)派生类,使用 Base 类进行模板化

entity-framework - Entity Framework 、继承和命名空间

c++ - move 构造函数不是继承的,也不是默认生成的