我的模板有问题-虚拟功能不匹配。
首先,我有一个名为Unit
的父类。
和2个子类Hero
和Monster
。
这两个类都有两个子类,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++不允许这样做。
我应该怎么写这些虚函数?
或者我可以使用一些通用指针(如果有这样的东西)来代替模板吗?
我想使用来自不同怪物和英雄的攻击功能,所以我必须使用模板。如果我尝试编写不同的函数,例如
attackHero
和attackMonster
,则其中之一将不起作用,因为当我这样做时,我基本上是在尝试采用某些不存在的类的 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/