C++ C++;具有基类的唯一静态id和类名
拥有类C++ C++;具有基类的唯一静态id和类名,c++,rtti,C++,Rtti,拥有类TaskBase,它的每个派生类都必须具有名称和唯一id 任务库如下所示: class TaskBase { public: static const int id() { // return an unique id, for each object or derived class, HOW ?? } static const string name() { // return class name for ea
TaskBase
,它的每个派生类都必须具有名称和唯一id
任务库如下所示:
class TaskBase
{
public:
static const int id()
{
// return an unique id, for each object or derived class, HOW ??
}
static const string name()
{
// return class name for each derived class, HOW ??
// for example : "TaskBase" for this class
}
};
我的尝试是:
template <typename DERIVED>
class TaskBase
{
public:
static const int id()
{
static const int id = reinterpret_cast<int> (typeid (DERIVED).name());
return id;
}
static const string name()
{
static string n;
if (!n.size())
{
int status;
char *realname = abi::__cxa_demangle(typeid (DERIVED).name(), 0, 0, &status);
n = realname;
free(realname);
}
return n;
}
};
咬紧牙关C++,你可能需要咬紧牙关,做一些额外的簿记。在存储所有类名的某处创建枚举:
enum ClassID {
MYTASK1_CLASS,
MYTASK2_CLASS
};
创建一个新类时,添加一个新的classId并不需要那么长时间
我以前做过这个。做我上面描述的事情就足够了。但是如果使用足够聪明的宏设置枚举值,则可以对类的层次结构进行编码,并仅从ClassID和位掩码实现动态强制转换和instanceof 我建议实现纯虚拟方法来获取基类中的类名和ID。子体需要提供唯一的名称和ID
class TaskBase
{
private:
const void* m_id;
string m_name;
public:
TaskBase(const void* m_id, string m_name): m_id(m_id), m_name(m_name)
{
}
const void* id() const
{
return m_id;
}
string name() const
{
return m_name;
};
};
template< typename DERIVED >
class TaskProxy: public TaskBase
{
public:
static const void* id()
{
//if you want to have for each object a unique id:
//return reinterpret_cast<void*>(this);
//just for each TaskProxy<????>:
return reinterpret_cast<const void*>(typeid( DERIVED ).name());
}
static string name()
{
return typeid( DERIVED ).name();
}
TaskProxy(): TaskBase(id(), name()) {}
};
class TaskBase
{
public:
virtual std::string get_task_name(void) const = 0;
virtual unsigned long get_task_id(void) const = 0;
};
我进一步采纳@VoidStar的建议,将这些名称放入一个(单个)公共类:
class TaskNames
{
protected:
static std::string get_tas1_name();
};
class Task1: public TaskBase, public TaskNames
{
//...
};
显示TaskBase::id和TaskBase::name的一些用例。谢谢您的回答,但是
静态方法在哪里?如果没有对象实例,我怎么能拥有MyTask2::id()
?嗯,你为什么需要这个?如果你想从TaskBase
中检查name()
和id()
,我们需要它virtual
,但你可以做到:TaskProxy().id()
或者您添加了一个具有不同名称的静态
函数,因为我们无法使用它虚拟
&静态
(谁知道为什么…)是的,您非常接近我的预期解决方案,但是我想知道是否存在静态
方法的模式?@Masoud:您可以给TaskProxy
类一些静态方法[非静态版本可以简单地调用这些方法],但它们不属于TaskBase
中,正如您最初显示的那样。当我在.cpp
文件中编写静态方法体时,存在链接问题:未定义对“TaskProxy::name()”的引用。
。我必须在.h
中编写它们的主体吗?还有其他方法可以做到这一点,但这是一种有效的方法(像typeid
这样的方法要求所讨论的类具有虚拟成员函数,这排除了很多类)。
Name: 7MyTask1 Id:0x401228
Name: 7MyTask2 Id:0x4011c0
class TaskBase
{
public:
virtual std::string get_task_name(void) const = 0;
virtual unsigned long get_task_id(void) const = 0;
};
class TaskNames
{
protected:
static std::string get_tas1_name();
};
class Task1: public TaskBase, public TaskNames
{
//...
};