gpt4 book ai didi

c++ - 使用成员变量的地址作为ID

转载 作者:行者123 更新时间:2023-11-28 03:26:33 25 4
gpt4 key购买 nike

我试图避免声明枚举或使用字符串。虽然这样做的理由可能看起来可疑,但完整的解释是无关紧要的。

我的问题很简单。我可以使用成员变量的地址作为唯一 ID 吗?

更具体地说,要求是:

  • ID 无需序列化。
  • ID 将是 protected 成员 - 仅供拥有对象在内部使用(即使在相同的类实例之间也不会比较 ID)。
  • 子类需要访问基类 ID 并可以添加它们的新 ID。

所以第一个解决方案是这样的:

class SomeClass
{
public:
int mBlacks;

void AddBlack( int aAge )
{
// Can &mBlacks be treated as a unique ID?
// Will this always work?
// Is void* the right type?
void *iId = &mBlacks;

// Do something with iId and aAge
// Like push a struct of both to a vector.
}
};

虽然第二种解决方案是这样的:

class SomeClass
{
public:
static int const *GetBlacksId()
{
static const int dummy = 0;
return &dummy;
}

void AddBlack( int aAge )
{
// Do something with GetBlacksId and aAge
// Like push a struct of both to a vector.
}
};

最佳答案

此对象的其他 int 数据成员,以及同一进程中 SomeClass 的不同实例的 mBlacks 成员,都没有与此 SomeClass 实例的 mBlacks 成员地址相同。因此,您可以安全地将其用作流程中的唯一 ID。

SomeClass 的空基类子对象可以与 mBlacks 具有相同的地址(如果 SomeClass 有任何空基类,它没有't),char 对象是 mBlacks 的第一个字节,其地址与 mBlacks 相同。除此之外,没有其他对象具有相同的地址。

void* 将用作类型。 int* 也可以,但也许您想要为不同的 ID 使用不同类型的数据成员。

但是,该 ID 对于此实例是唯一的。同一类型的不同实例具有不同的 ID。您的评论之一表明这实际上不是您想要的。

如果您希望该类型的每个 都有一个唯一的 ID,并且所有具有相同值的对象都具有相同的 ID,那么您最好将 ID 组合为对象的所有重要字段。或者只是比较对象的相等性而不是它们的 ID,使用合适的 operator==operator!=

或者,如果您希望 ID 唯一标识一个值何时首次构造而不是通过复制构造函数和复制赋值(以便作为相同“原始”拷贝的所有对象共享一个 ID ),那么这样做的方法是在所有其他构造函数中分配一个新的唯一 ID,将其存储在数据成员中,然后将其复制到复制构造函数和复制赋值运算符中。

获取新 ID 的规范方法是使用全局 [*] 计数器,每次取值时该计数器都会递增。这可能需要根据哪些程序使用该类(以及它们如何使用它)使其成为线程安全的。如果计数器的类型足够大,则值在给定的程序运行中将是唯一的。

另一种方法是生成一个 128 位的随机数。这在理论上并不令人满意,但假设有一个不错的随机源,发生碰撞的可能性不会大于您的程序因某些不可避免的原因(如宇宙射线引起的数据损坏)而失败的可能性。当对象的来源广泛分布时(例如,如果您需要在不同进程或不同机器中唯一的 ID),随机 ID 比顺序 ID 更容易。如果您选择使用机器的 MAC 地址、随机数、时间、每个进程的全局 [*] 计数器、PID 以及您想到的任何其他内容的组合,则可以你动手(或 a standard UUID )。但这可能无法满足您的需求。

[*] 不一定是全局的 - 它可以是类的私有(private)静态数据成员,或函数的静态局部变量。

关于c++ - 使用成员变量的地址作为ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13756078/

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