想象一下,我有这样的类层次结构:
Base
A : Base
B : Base
C : B
我希望能够从string
对象Base
中检索(I need string, not enum)
类型。我还希望能够将对象类型与A
类型进行比较,例如:
Object *object = new A();
if (object->type() == A::typename())
{
//hooray!
}
目前我正在计划为每个班级添加静态功能:
static string typename() {return "Different name for each class";}
然后我将不得不为每个派生类重新实现Base
函数virtual string type()
:
A: virtual string type() {return typename();} //A::typename
B: virtual string type() {return typename();} //B::typename
...
我认为这样的设计看起来很难看。有没有更好的方法来实现我的目标?
为什么我需要这个: 我正在开发一款游戏。有一个瓷砖地图。每个图块上都有一个对象数组。某些对象可以放在其他对象上。所以我想检查是否允许将对象放在特定的磁贴上。例如:如果tile具有类型" pot"然后花可以放在那里。
答案 0 :(得分:3)
您可以使用dynamic_cast
实现相同的目标。无论如何,你的课程都是多态的。
注意这至少是代码味道。您不需要在经过深思熟虑的设计中找到实际类型的类。您试图解决的根本问题是什么?
此外,typename
是C ++中的关键字,您应该以不同的方式命名您的方法。
编辑:一个可能更好的解决方案是拥有一个可以堆叠的对象列表,并拥有虚拟方法:
class Object
{
virtual bool canStack(const std::string& baseObject) = 0;
};
class Flower
{
virtual bool canStack(const std::string& baseObject)
{
if ( baseObject == "pot" )
return true;
return false;
}
};
现在我明白为什么你想得到这个名字。
答案 1 :(得分:0)
我正在寻找一种舒适的方式来做这几天。 这是我最终做到的。该解决方案实用,编译速度快,便于携带,无需RTTI 。 然而,它使用#define,C ++人员经常试图避免。 也许有人可以将代码转换为使用模板的代码,我也会对此感兴趣。
基本上,指向静态方法的指针用于与“static bool IsTypeOf(_TypeCheckBase& other)”中的“other”对象返回的指针进行比较,以便提供类型检查。 此外,您还可以获取对象的名称。
#define TYPE_CHECK_IMPL(T) \
static bool IsTypeOf(_TypeCheckBase& other) { \
return other.GetType() == (unsigned int)&IsTypeOf; } \
virtual unsigned int GetType() { \
return (unsigned int)&IsTypeOf; } \
public: virtual const string& GetTypeName() { \
static string typeName = #T; \
return typeName; }
#define TYPE_CHECK_DECL(T) \
typedef T _TypeCheckBase;\
TYPE_CHECK_IMPL(T)
class root
{
public:
TYPE_CHECK_DECL(root)
};
class A: public root
{
public:
TYPE_CHECK_IMPL(A)
};
class AA: public A
{
public:
TYPE_CHECK_IMPL(AA)
};
class B: public root
{
public:
TYPE_CHECK_IMPL(B)
};
不,您可以执行以下操作:
inline void prn(std::string txt, bool val)
{
cout << txt << ": " << (val ? "true":"false") << endl;
}
#define CMP(foo,bar) prn(#foo "\tis type of " #bar " TypeName:\"" + bar.GetTypeName() + "\"", foo::IsTypeOf(bar));
int main(void)
{
A a; AA aa;
B b;
cout << endl;
CMP(A,a);
CMP(AA,a);
CMP(B,a);
CMP(A,aa);
CMP(AA,(*((A*)&aa)));
CMP(B,aa);
CMP(A,b);
CMP(AA,b);
CMP(B,b);
}
您在这里使用的主要方法是:
bool Foo :: IsTypeOf(bar),其中Foo是类类型,bar是对象,直接或间接从您的根类类型派生。
string bar.GetTypeName()