gpt4 book ai didi

c++ - CRTP 和唯一持久标识符

转载 作者:行者123 更新时间:2023-11-30 02:35:05 30 4
gpt4 key购买 nike

考虑以下代码:

#include <iostream>
#include <cstdlib>
#include <ctime>

struct BaseClass {
static int identifier() {
static int identifier_counter = 0;
return identifier_counter++;
}
};

template <class D>
struct Class: public BaseClass {
static int identifier() {
static int class_identifier = BaseClass::identifier();
return class_identifier;
}
};

struct A: public Class<A> { };
struct B: public Class<B> { };

int main() {
std::srand(std::time(0));
int r = std::rand()%2;

if(r) {
std::cout << "A: " << A::identifier() << std::endl;
std::cout << "B: " << B::identifier() << std::endl;
} else {
std::cout << "B: " << B::identifier() << std::endl;
std::cout << "A: " << A::identifier() << std::endl;
}
}

这是对问题的简化但仍然合理的表示。

任何派生类在运行时都会有一个特定的、不同的标识符,并且相同类型的两个实例将共享相同的标识符。对于这样的问题当然是一个很好的解决方案。

不幸的是,这些标识符取决于调用 identifier 成员的顺序(我们可以通过多次运行示例轻松地看到它)。换句话说,给定两个类 AB,如果碰巧运行两次软件,它们的 identifier 成员以不同的顺序被调用,它们有不同的标识符。

我的问题是,出于某些原因,我需要将这些标识符存储在某处,并让它们在单次执行后继续存在,这样我就可以在应用程序再次运行时根据原始类型进行推理,并决定从存储。

另一种方法是使用 hash_code来自 type_info,但它还有其他问题。另一种解决方案是在应用程序的 Bootstrap 期间强制调用 identifier 成员,但是这个也有几个缺点。

我想知道到目前为止是否有一种易于实现但仍然优雅的解决方案,它对开发人员完全透明,可以在多次执行中识别类型,因为上面的解决方案是针对应用程序的单次运行。

最佳答案

C++ 无法解决每个类都具有唯一持久标识符的问题。对不起。您将依赖于调用初始化函数的顺序,或者,如果您从静态对象的初始化器中调用它们,则取决于静态初始化器的顺序(这通常取决于链接行中目标文件的顺序)。

当然,不能保证哈希值是唯一的。

为此您必须使用外部脚本。特别是,可能会使用这样的东西:

// when class is first created
class Foo {
static int class_id = ?CLASS_ID?;
};

// after class is process by the script
class Foo {
static int class_id = 123; // Autogenerated by 'stamp_id.pl'
};

你可能有一个 perl 脚本作为编译的一部分运行(第一件事),它打开项目目录中的所有 .h 文件,读取所有这些文件,计算 Autogenerated by 'stamp_id.pl 的所有实例' 然后用递增的计数器标记所有 ?CLASS_ID?(从已经生成的 ID 的数量开始)。为了增加一些安全性,您可能需要一个比简单的 ?...? 更好的模式,但我认为,您明白了。

关于c++ - CRTP 和唯一持久标识符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34008110/

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