C++中的多态和获取对象类型 [英] Polymorphism and get object type in C++
问题描述
假设我有 4 个类,B,C,D,E
,它们继承自 A
(抽象基类).另外我有一个 A*
类型的容器(std::vector
),它的内容指向B,C,D,E
对象.以下是一些规则:如果 B
对象和 C
对象交互,它们会从向量中移除,并在它们的位置创建 D
对象.
Let's say that I have 4 classes, B,C,D,E
that inherit from A
(abstract base class).
Also I have a container (std::vector
) of type A*
whose contents point to either of
B,C,D,E
objects.
Here are some rules:
If a B
object and a C
object interact, they get removed from the vector and in their place a D
object gets created.
另外,C + D = E
现在,假设我随机选择上述矢量内容之一;为了实现交互机制,我将如何知道哪个对象属于哪种类型?
Now, suppose that I randomly choose one of said vector contents; how would I go about knowing which object is of which type, in order to implement an interaction mechanic?
注意:我不希望使用 typeid
运算符、动态转换或标志.还有其他解决方案吗?
NOTE: I do not wish to use the typeid
operator, a dynamic cast or flags. Any other solutions?
这是一些代码
#include <iostream>
class A {
protected:
int v;
public:
A(){}
~A(){}
};
class B :public A {
public:
B(){}
~B(){}
};
class C : public A {
public:
C(){}
~C(){}
};
class D : public A {
public:
D(){}
~D(){}
};
class E : public A {
public:
E(){}
~E(){}
};
int main()
{
std::vector<A*> container;
return 0;
}
我将如何实现交互功能?
How would I implement the interact function(s) ?
推荐答案
你可以使用虚函数来做多分派
You may use virtual functions to do the multiple dispatch
struct B;
struct C;
struct D;
struct E;
struct A
{
virtual ~A() = default;
virtual std::unique_ptr<A> interactWithA(const A&) const = 0;
//protected:
virtual std::unique_ptr<A> interactWithB(const B&) const = 0;
virtual std::unique_ptr<A> interactWithC(const C&) const = 0;
virtual std::unique_ptr<A> interactWithD(const D&) const = 0;
virtual std::unique_ptr<A> interactWithE(const E&) const = 0;
};
// Your interact rules
template <typename LHS, typename RHS>
std::unique_ptr<A> interact(const LHS&, const RHS&) { return nullptr; }
// Note that definitions and declarations must be split in reality
// to be able to compile it
std::unique_ptr<A> interact(const B&, const C&) { return std::make_unique<D>(); }
std::unique_ptr<A> interact(const C&, const D&) { return std::make_unique<E>(); }
// Maybe the reflexive case, C/B D/C ?
// The derived classes
struct B : A
{
std::unique_ptr<A> interactWithA(const A& a) const override { return a.interactWithB(*this); }
// Even if code look similar for other inherited class
// the difference is in the runtime type of the objects are known.
std::unique_ptr<A> interactWithB(const B& rhs) const override { return interact(rhs, *this); }
std::unique_ptr<A> interactWithC(const C& rhs) const override { return interact(rhs, *this); }
std::unique_ptr<A> interactWithD(const D& rhs) const override { return interact(rhs, *this); }
std::unique_ptr<A> interactWithE(const E& rhs) const override { return interact(rhs, *this); }
};
struct C : A
{
std::unique_ptr<A> interactWithA(const A& a) const override { return a.interactWithC(*this); }
std::unique_ptr<A> interactWithB(const B& rhs) const override { return interact(rhs, *this); }
std::unique_ptr<A> interactWithC(const C& rhs) const override { return interact(rhs, *this); }
std::unique_ptr<A> interactWithD(const D& rhs) const override { return interact(rhs, *this); }
std::unique_ptr<A> interactWithE(const E& rhs) const override { return interact(rhs, *this); }
};
struct D : A
{
std::unique_ptr<A> interactWithA(const A& a) const override { return a.interactWithD(*this); }
std::unique_ptr<A> interactWithB(const B& rhs) const override { return interact(rhs, *this); }
std::unique_ptr<A> interactWithC(const C& rhs) const override { return interact(rhs, *this); }
std::unique_ptr<A> interactWithD(const D& rhs) const override { return interact(rhs, *this); }
std::unique_ptr<A> interactWithE(const E& rhs) const override { return interact(rhs, *this); }
};
struct E : A
{
std::unique_ptr<A> interactWithA(const A& a) const override { return a.interactWithE(*this); }
std::unique_ptr<A> interactWithB(const B& rhs) const override { return interact(rhs, *this); }
std::unique_ptr<A> interactWithC(const C& rhs) const override { return interact(rhs, *this); }
std::unique_ptr<A> interactWithD(const D& rhs) const override { return interact(rhs, *this); }
std::unique_ptr<A> interactWithE(const E& rhs) const override { return interact(rhs, *this); }
};
然后
std::vector<std::unique_ptr<A>> v /* = .. */;
auto a = v[i]->interactWithA(*v[j]);
if (a) {
// Remove v[i] and v[j]
// Insert a
}
这篇关于C++中的多态和获取对象类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!