在c++中初始化一个对象数组具有特殊的价值

发布于 2024-12-17 07:08:32 字数 401 浏览 0 评论 0原文

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

我尝试在 C++ 中使用 null 定义,但发现它只是一个“-1” int 值,我无法正确使用它。所以基本上我需要一些东西来区分数组中的空闲位置和已占用的位置。

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

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

I am an intermediate java programmer and I am used to relaying on the null value in java for cheking if objets are initialized with some reference to instanced object in memory. I want to do something similar in c++ but I do not have a clear idea about how I can achieve it. I want to initialize a user array - user is a class I have defined - so I can check if the actual position in the array does contain an object or it is free.

I have tried to use the null definition in c++ but found out that it is simply a "-1" int value and I could not use it properly. So basically I need something to distinguish between a free position in my array and an ocuppied one.

Additionally I might be interested in having an extra value to distinguish a position that contained a removed user, since I am planning to just mark the desired position with a special mark as a freed position when it comes to the method that remove a user from the array.

For the curious ones, I am implementing a simple hash set and the remove method in my class just mark the position of the element to remove instead of doing some restruction.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一江春梦 2024-12-24 07:08:32

首先,null 定义不是 -1 而是 0。假设你有类似的东西,

class User
{
};

User RemovedClass;

你可以有这样的东西

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

这里 0 是一个新用户,1 是 java null 等价物, 2 是已删除班级的标记。

编辑

通常,当您在java中看到User数组时,您必须将其映射到C++中的User*数组。

经过这些操作。

User a;
User b;
a = b;

在java中a和b将引用相同的用户。在 C++ 中,这样的代码将产生 a 和 b 引用两个不同的 User 对象。

First of all null definition is not -1 but 0. Assuming you have something like

class User
{
};

User RemovedClass;

you can have something like this

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

Here 0 is a new User, 1 is java null equivalent , 2 is marker for deleted class.

EDIT

Typically when you see User array in java you will have to map it to a User* array in C++.

After these operations.

User a;
User b;
a = b;

in java a and b will refer to the same User. In C++ such code will yield to a and b referring to two different User objects.

ゃ懵逼小萝莉 2024-12-24 07:08:32

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

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

因此,如果您说您有一个“用户数组”并且想要跟踪某个位置,那么这在某种程度上是矛盾的已初始化。

除非:

  1. 您不是创建用户数组,而是创建“指向用户的指针”数组(或其他引用,例如 auto_ptr)。这样,说某个元素为“null”就有意义了;或

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

(首先,当您编写 C++ 时,我建议您使用 std::vector,而不是数组。但是我在这个答案中使用数组,以便紧贴您的问题)

对于情况 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 并不是您真正想要的)

I think there are some concept you need to understand.

Unlike Java, when you are creating an N-element array of User, it is NOT an array of reference. It is really a piece of memory containing actual N user, which is already created and initialized (i.e. constructor already run). (Well, there are more advanced topics like placement-new but I think it is not really what you are looking for yet)

So it is somehow contradicting if you said you have an "array of User" and want to keep track if certain position is initialized.

Unless:

  1. You are not creating array of User, but Array of "Pointer to User" (or other reference like auto_ptr). By such way, it is meaningful to say certain element is "null"; or

  2. Your "initialize" do not mean creating an object instance, but an explicit initialization action (like executing an init() method of an User instance). By such way, it is meaningful to say certain element is "not initialized".

(First of all, as you are writing C++, I shall recommend you to use std::vector, not array. However I am using array in this answer, as to stick close to your question)

For case 1, it is strict forward, simply use NULL (avoid using 0, because, although NULL is defined as 0 in most system, using NULL actually makes the code more readable and more portable):

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

For case 2, you have many other choice, like keeping another array of boolean to keep the "initialized" flag, or have a wrapper over User for such extra flag, or simply add such flag into your User class, etc.

e.g.

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(...);
}

(honestly I think case 2 is not really what you are looking for)

夕嗳→ 2024-12-24 07:08:32

我使用 boost::可选:

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!"; }

I use 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!"; }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文