Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;具有基类的唯一静态id和类名_C++_Rtti - Fatal编程技术网

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
{
//...
};