用特殊值初始化c++中的对象数组

Initialize an object array in c++ with a special value

本文关键字:对象 数组 c++ 初始化      更新时间:2023-10-16

我是一名中级java程序员,我习惯于依赖java中的null值来检查对象是否初始化,并引用内存中的实例化对象。我想在c++中做一些类似的事情,但我不清楚如何实现它。我想初始化一个用户数组——user是我定义的一个类——这样我就可以检查数组中的实际位置是否包含对象或者它是空闲的。

我试图在c++中使用null定义,但发现它只是一个"-1"int值,我无法正确使用它。因此,我需要一些东西来区分数组中的空闲位置和已占用位置。

此外,我可能有兴趣使用一个额外的值来区分包含已删除用户的位置,因为我计划在涉及从数组中删除用户的方法时,仅将所需的位置用特殊标记标记为释放位置。

对于好奇的人,我正在实现一个简单的哈希集,并且在我的类中的remove方法只是标记要删除的元素的位置,而不是做一些重构。

首先null定义不是-1而是0。假设你有像

这样的东西
class User
{
};
User RemovedClass;

你可以这样写

User *arr[3];
arr[0] = new User();
arr[1] = 0;
arr[2] = &RemovedClass;

这里0是一个新的User, 1是java null等价,2是删除类的标记。

编辑

通常当你在java中看到User数组时,你必须将它映射到c++中的User*数组。

操作完成后。

User a;
User b;
a = b;
java a和b中的

将指向相同的User。在c++中,这样的代码将产生a和b,它们引用两个不同的User对象。

我认为有一些概念你需要理解。

与Java不同,当你创建一个包含n个元素的User数组时,它不是一个引用数组。它实际上是一块包含实际N个用户的内存,它已经被创建和初始化(即构造函数已经运行)。(嗯,还有更高级的主题,如位置-新,但我认为这不是你真正想要的)

所以如果你说你有一个" User数组"并且想要跟踪某个位置是否被初始化,这在某种程度上是矛盾的

除非:

  1. 你不是在创建用户数组,而是"指向用户的指针"数组(或其他引用,如auto_ptr)。这样,说某个元素为"null"是有意义的;或者

  2. 你的"initialize"并不意味着创建一个对象实例,而是一个显式的初始化操作(比如执行一个User实例的init()方法)。通过这种方式,表示某个元素"未初始化"是有意义的。

(首先,当你在编写c++时,我建议你使用std::vector,而不是array。然而,我在这个答案中使用数组,以坚持接近你的问题)

对于情形1,它是严格向前的,只需使用NULL(避免使用0,因为,尽管在大多数系统中NULL被定义为0,使用NULL实际上使代码更具可读性和可移植性):

User* user[10] = {NULL};   // array of 10 pointer-to-User
user[0] = new User(...);
assert (user[0] != NULL);
assert (user[1] == NULL);

对于情况2,您有许多其他选择,例如保留另一个布尔数组以保持"初始化"标志,或者在User上为此类额外标志使用包装器,或者简单地将此类标志添加到您的User类中,等等。

User user[10];   // 10 element of User, which all of them is already created
//assume you have extra flag in User
user[0].init(...);  // explicity do some init work on user[0]
//......
if (! user[5].isInitialized()) {
  user[5].init(...);
}

(老实说,我认为情况2不是你真正想要的)

我使用boost::optional:

boost::optional<int> a;
if (!a) { std::cout << "no a!"; }
a = 5;
if (a) { std::cout << "a = " << *a; }
a = boost::none;
if (!a) { std::cout << "no a!"; }