C++ 在C+;中存储对象类型的好方法是什么+;?
假设我有这样的类层次结构:C++ 在C+;中存储对象类型的好方法是什么+;?,c++,inheritance,types,C++,Inheritance,Types,假设我有这样的类层次结构: Base A : Base B : Base C : B 我希望能够从Base对象检索字符串类型(我需要字符串,而不是枚举)。我还希望能够将对象类型与A类型进行比较,例如: Object *object = new A(); if (object->type() == A::typename()) { //hooray! } 现在,我计划为每个类添加一个静态函数: static string typename() {return "Different
Base
A : Base
B : Base
C : B
我希望能够从Base
对象检索字符串类型(我需要字符串,而不是枚举)
。我还希望能够将对象类型与A
类型进行比较,例如:
Object *object = new A();
if (object->type() == A::typename())
{
//hooray!
}
现在,我计划为每个类添加一个静态函数:
static string typename() {return "Different name for each class";}
然后我必须为每个派生类重新实现Base
函数虚拟字符串类型()
:
A: virtual string type() {return typename();} //A::typename
B: virtual string type() {return typename();} //B::typename
...
我觉得这样的设计很难看。有没有更好的方法来实现我的目标
我为什么需要这个:
我正在开发一个游戏。有一张平铺地图。每个磁贴上都有一组对象。某些对象可以放置在其他对象上。因此,我想检查是否允许将对象放置在特定的磁贴上。例如:如果瓷砖具有类型为“pot”的对象,则可以将花放在那里。您可以使用动态\u cast
实现同样的效果。你的类是多态的
注意这至少是一种代码气味。您不需要在经过深思熟虑的设计中找到实际类型的类。你想解决什么潜在的问题
也可以,<代码> >类型名称<代码>是C++中的关键字,应该对方法进行不同的命名。p>
编辑:一个可能更好的解决方案是有一个可以堆叠的对象对列表,并有虚拟方法:
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;
}
};
现在我明白了为什么要使用get名称。使用动态\u cast
可以实现同样的效果。你的类是多态的
注意这至少是一种代码气味。您不需要在经过深思熟虑的设计中找到实际类型的类。你想解决什么潜在的问题
也可以,<代码> >类型名称<代码>是C++中的关键字,应该对方法进行不同的命名。p>
编辑:一个可能更好的解决方案是有一个可以堆叠的对象对列表,并有虚拟方法:
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;
}
};
现在我明白你为什么想要这个名字了。几天来我一直在寻找一种舒适的方法。
下面是我最后是怎么做到的。该解决方案实用、编译速度快、可移植,且无需RTTI即可工作。
但是,它使用的是一个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);
}
inline void prn(std::string txt,bool val)
{
好几天来,我一直在寻找一种舒适的方法来做这件事。
下面是我最终的解决方案。该解决方案实用、编译速度快、可移植且无需RTTI。
但是,它使用的是一个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);
}
inline void prn(std::string txt,bool val)
{
您是否知道type_id
对象?()您到底想实现什么?如果您想要每个类的特定行为,请实现一个基方法,该基方法将被每个继承类覆盖,并实现其特定的behvior。测试“的实例”不是OOP的内容。如果您需要有关对象类型的信息,而不是通过访问对象的指针或引用所知道的信息,则可能需要检查OOP设计。@giorashc:请参阅我的编辑,查看访问者模式。您知道type\u id
对象吗?()你到底想实现什么?如果你想为每个类实现一个特定的行为,实现一个基类方法,该基类方法将被每个继承类覆盖,并实现其特定的behvior这不是OOP的意义所在。如果您需要有关对象类型的信息,而不是通过访问对象的指针或引用所知道的信息,则可能需要检查OOP设计。@giorashc:请参阅我的编辑,查看访问者模式。Luchian:我更喜欢将字符串常量作为常量存储。另外因为游戏中会有很多类型,我不想依赖于我输入“pot”不会出错@Andrew如果你有一个可接受的组合集合,那么维护起来就会容易得多。Luchian:我更喜欢将字符串常量存储为常量。另外,因为游戏中会有很多类型,我不想依赖这些类型,我不会错误地键入“pot”@Andrew如果您有一组可接受的组合,那么维护起来就会容易得多。