gpt4 book ai didi

c++ - 由可通过基类访问的最派生类定义的唯一 ID

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:02:23 25 4
gpt4 key购买 nike

好吧,我的想法是我有一个“组件”的映射,它继承自 componentBase,并以最衍生*唯一的 ID 为键。

只是,我想不出一个好的方法来让它工作。我用构造函数试过了,但那不起作用(也许我做错了)。任何虚拟等继承技巧的问题在于用户必须在底部实现它们,这可能会被遗忘并使其变得不那么……干净。

*正确的短语?如果->是继承; foo 最派生:foo->foo1->foo2->componentBase

下面是一些显示问题的代码,以及为什么 CRTP 无法解决问题:(不,这不是合法代码,但我正在努力表达我的想法)

#include<map>

class componentBase
{ public: virtual static char idFunction() = 0; };

template <class T>
class component
: public virtual componentBase
{
public:
static char idFunction(){ return reinterpret_cast<char>(&idFunction); }
};

class intermediateDerivations1
: public virtual component<intermediateDerivations1>
{
};

class intermediateDerivations2
: public virtual component<intermediateDerivations2>
{ };

class derived1
: public intermediateDerivations1
{ };

class derived2
: public intermediateDerivations1
{ };


//How the unique ID gets used (more or less)
std::map<char, componentBase*> TheMap;

template<class T>
void addToMap(componentBase * c)
{
TheMap[T::idFunction()] = c;
}

template<class T>
T * getFromMap()
{
return TheMap[T::idFunction()];
}

int main()
{

//In each case, the key needs to be different.

//For these, the CRTP should do it:
getFromMap<intermediateDerivations1>();
getFromMap<intermediateDerivations2>();

//But not for these.
getFromMap<derived1>();
getFromMap<derived2>();

return 0;
}

或多或少,无论用户做什么,我都需要始终存在的东西,并且具有最派生类所独有的可排序值。

此外,我意识到这不是最常问的问题,实际上我遇到了一些意想不到的困难,难以用语言表达,所以如果/何时需要澄清,请提出问题。

编辑:使用 Beta 的措辞; class derived2 有一个 ID 号,在从 ComponentBase 派生的所有类中是唯一的,并且没有其他类派生自它 - 除了不应该有我们处理实例的使用情况我们不知道派生最多的类型。也就是说,我们永远不必处理实际上指向 ``foo` 的 foo1*

任何时候我需要访问这个 ID,我都有关于最派生类的类型信息;通过 addComponent、getComponent 和 removeComponent 的模板化特性。

嗯,换一种说法;我需要在知道类型的情况下将类型“转换”为唯一数字,以便以后当我没有类型信息时可以区分两件事。

最佳答案

我不明白你为什么在类组件中使用reinterpret_cast

就拥有唯一 ID 而言,您应该有某种流程来验证该 ID 未被任何派生实例使用。

另一方面,每个类都应该实现一个static clonecreate 方法。 工厂 会有一个 map 的。函数指针指向特定类的createclone 方法。由于 std::map 无法在编译期间创建为 const 静态实体,因此我通常使用常量静态数组来保存 ID 和函数指针。如果数组很小,它对 map 的性能影响不大。

例子:

class Base
{;};

// Declare a synonym for a pointer to the creation function.
typedef Base * (*P_Creation_Function)(unsigned int id);

struct Creation_Entry
{
unsigned int class_id;
P_Creation_Function p_creator;
};

class Child1 : public Base
{
public:
static Base * create(unsigned int id);
};

Creation_Entry creation_table[] =
{
{1, Child1::create},
};

static const unsigned int NUM_CREATORS =
sizeof(creation_table) / sizeof(creation_table[0]);

// Process 1: search table for ID
for (unsigned int i = 0; i < NUM_CREATORS; ++i)
{
if (creation_table[i].class_id == new_id)
{
return (*creation_table[i].p_creator)(new_id);
}
}

// Process 2: Execute each creation function in the table.
// Creation functions will return NULL if the ID is not a match
Base * p_new_object;
for (unsigned int j = 0; j < NUM_CREATORS; ++j)
{
p_new_object = (*creation_table[j].p_creator)(new_id);
if (p_new_object)
{
return p_new_object;
}
}

对于小型项目,与其他瓶颈(例如磁盘 i/o)相比,创建函数返回 NULL 的开销并不显着。第二个过程不需要工厂知道类 ID;类 ID 仍然封装在类中。

我已经使用了这两个流程,并根据我的心情和项目规模实现它们。 :-)

关于c++ - 由可通过基类访问的最派生类定义的唯一 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2466505/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com