内容
您好。
我遇到了问题。我有一个 A 的类,其基数 B (是多态的)。在 B 类中是方法Print(),它是虚拟的。在 A 类中也是Print()。虚拟。 假设我给了一个A类型的对象(或指针),存储在B变量
中B * object = new A();
通过致电
object->Print();
它调用A类中的方法,但我也希望它在B类中调用方法。 技术上 我想为每个孩子调用该方法,直到我到达没有孩子的课程 这可以按如下方式完成:
class A
{
public:
virtual void Print() const override
{
cout << "A" << endl;
}
};
class B : public A
{
public:
virtual void Print() const override
{
cout << "B" << endl;
A::Print(); // i do not want to call it here...
}
};
问题是我确实不想被迫拨打
A::Print();
是的,你可能会问,这笔交易是什么...... 我有很长的继承链。 (假设继承链中有15-20个类)。 在游戏中,每个人都会做一些小事。
让我们说
class GameObject
{
public:
virtual void Update() const
{
//updates position, recounts it towards screen
}
};
class Character : public GameObject
{
public:
virtual void Update() const override
{
// Updates lives, movement
}
};
class Warrior : public Character
{
public:
virtual void Update() const override
{
// Updates armor, specific stuff
}
};
现在这个例子非常简单。问题是,如果我忘记添加一个调用基地:: Update()那么我很烦,为什么它不起作用。寻找这样的错误很难。我的意思是,如果有什么办法吗?
非常感谢您的回复。
度过愉快的一天
答案 0 :(得分:5)
如果确实每个类都必须调用基函数,那么确保强制执行功能的一种方法是使用template pattern。
class GameObject
{
public:
void Updater()
{
Update(); // this is a virtual call
GameObject::Update(); // now call base
}
virtual void Update() const
{
}
};
class Character : public GameObject
{
public:
virtual void Update() const override
{
// Updates lives, movement
}
};
class Warrior : public Character
{
public:
virtual void Update() const override
{
// Updates armor, specific stuff
}
};
class Character : public GameObject
{
public:
virtual void Update() const override
{
// Updates lives, movement
}
};
class Warrior : public Character
{
public:
virtual void Update() const override
{
// Updates armor, specific stuff
}
};
然后始终致电YourObject::Updater();
而不是YourObject::Update()
。 Updater
函数将调用对象的Update
函数,然后返回并调用基类Update
。
答案 1 :(得分:1)
曾经有人建议获得某个类型(N2965)的所有基础,其中gcc实际上是在<tr2/type_traits>
中实现的。因此,如果可移植性不是一个问题,并且您恰好使用gcc,那么您可以像这样写一个全能:
struct A {
virtual ~A() = default;
virtual void print() { print_all(*this); }
void print_one() { std::cout << "A\n"; }
protected:
template <class T>
void print_all(T& object) {
object.print_one();
print_all(object, typename std::tr2::bases<T>::type{});
}
template <class T, class... Bases>
void print_all(T& object, std::tr2::__reflection_typelist<Bases...> ) {
using swallow = int[];
(void)swallow{0,
(static_cast<Bases&>(object).print_one(), 0)...
};
}
};
这会分割出print()
,它会打印所有内容,而print_one()
会打印出一种特定类型。您只需自己print()
来电print_all()
:
struct B : A {
void print() override { print_all(*this); }
void print_one() { std::cout << "B\n"; }
};
struct C : B {
void print() override { print_all(*this); }
void print_one() { std::cout << "C\n"; }
};
否则,您将不得不等待其中一个反思提案被采纳。