在管理 class 指针 C++ 的队列时,向量成员丢失
Vector member is lost while managing a queue of the class pointers C++
我有一个非常简单的 class 称为 AClass,它有两个成员:一个整数和一个整数向量。在我的程序中,我试图使用一个指向 class 的对象的指针队列,并在该队列上使用 while 循环,直到它为空。在那个 while 循环中,我有时会创建新对象并将它们添加到队列中以进行某些处理。我遇到的问题是,对于在该循环中创建的对象,矢量成员似乎丢失了。 int 成员是可以访问的。我不太明白为什么...
这里有一个小代码示例可以说明我的问题。
#include <iostream>
#include <vector>
#include <queue>
#include <string>
class AClass
{
public:
int a_number;
std::vector<int> a_vector;
void print()
{
std::cout << "a number: " << a_number << std::endl;
std::cout << "a vector: ";
for (size_t i = 0; i < a_vector.size(); i++)
{
std::cout << a_vector[i] << " ";
}
std::cout << std::endl;
}
};
int main()
{
std::queue <AClass*> aclass_pointers_queue;
AClass first_aclass_object;
first_aclass_object.a_number = 2;
first_aclass_object.a_vector = { 1,2,3,4,5 };
aclass_pointers_queue.push(&first_aclass_object);
int some_break_condition = 1;
while (!aclass_pointers_queue.empty())
{
AClass* current_class_object = aclass_pointers_queue.front();
current_class_object->print();
aclass_pointers_queue.pop();
AClass another_aclass_object;
another_aclass_object.a_number = 3;
another_aclass_object.a_vector = { 5,4,3,2,1 };
aclass_pointers_queue.push(&another_aclass_object);
if (some_break_condition >= 2)
{
break;
}
some_break_condition++;
}
return 0;
}
这是输出:
a number: 2
a vector: 1 2 3 4 5
a number: 3
a vector:
对于在 while 循环中创建的对象的向量,没有打印出任何内容。它的大小为零。
在 while
循环中,您正在添加指向队列的指针,该指针指向局部变量的地址。在循环的下一次迭代中,该变量消失,您拥有的指针不再有效。
您添加到队列中的第一个指针是在 main
期间存在的对象的地址,因此该指针是有效的。
您可以为添加到队列的指针分配内存。但是如果你选择走那条路,你应该更喜欢使用像 std::unique_ptr
这样的东西,而不是原始指针。
由于指向本地对象的悬垂指针导致您的程序表现出未定义的行为,该对象的生命周期以该对象创建的块结束(在您的情况下为 while
循环)。在您的情况下,最简单的解决方案是按值而不是指针存储对象,并让 std::queue
正确管理对象的生命周期。在更复杂的场景中(比如你不想 move/copy 个对象,或者队列可以多次包含同一个对象)你可以考虑通过智能指针(共享或唯一)在队列本身或某处存储动态分配的对象否则,您将确保您的队列不包含悬挂指针。
我有一个非常简单的 class 称为 AClass,它有两个成员:一个整数和一个整数向量。在我的程序中,我试图使用一个指向 class 的对象的指针队列,并在该队列上使用 while 循环,直到它为空。在那个 while 循环中,我有时会创建新对象并将它们添加到队列中以进行某些处理。我遇到的问题是,对于在该循环中创建的对象,矢量成员似乎丢失了。 int 成员是可以访问的。我不太明白为什么...
这里有一个小代码示例可以说明我的问题。
#include <iostream>
#include <vector>
#include <queue>
#include <string>
class AClass
{
public:
int a_number;
std::vector<int> a_vector;
void print()
{
std::cout << "a number: " << a_number << std::endl;
std::cout << "a vector: ";
for (size_t i = 0; i < a_vector.size(); i++)
{
std::cout << a_vector[i] << " ";
}
std::cout << std::endl;
}
};
int main()
{
std::queue <AClass*> aclass_pointers_queue;
AClass first_aclass_object;
first_aclass_object.a_number = 2;
first_aclass_object.a_vector = { 1,2,3,4,5 };
aclass_pointers_queue.push(&first_aclass_object);
int some_break_condition = 1;
while (!aclass_pointers_queue.empty())
{
AClass* current_class_object = aclass_pointers_queue.front();
current_class_object->print();
aclass_pointers_queue.pop();
AClass another_aclass_object;
another_aclass_object.a_number = 3;
another_aclass_object.a_vector = { 5,4,3,2,1 };
aclass_pointers_queue.push(&another_aclass_object);
if (some_break_condition >= 2)
{
break;
}
some_break_condition++;
}
return 0;
}
这是输出:
a number: 2
a vector: 1 2 3 4 5
a number: 3
a vector:
对于在 while 循环中创建的对象的向量,没有打印出任何内容。它的大小为零。
在 while
循环中,您正在添加指向队列的指针,该指针指向局部变量的地址。在循环的下一次迭代中,该变量消失,您拥有的指针不再有效。
您添加到队列中的第一个指针是在 main
期间存在的对象的地址,因此该指针是有效的。
您可以为添加到队列的指针分配内存。但是如果你选择走那条路,你应该更喜欢使用像 std::unique_ptr
这样的东西,而不是原始指针。
由于指向本地对象的悬垂指针导致您的程序表现出未定义的行为,该对象的生命周期以该对象创建的块结束(在您的情况下为 while
循环)。在您的情况下,最简单的解决方案是按值而不是指针存储对象,并让 std::queue
正确管理对象的生命周期。在更复杂的场景中(比如你不想 move/copy 个对象,或者队列可以多次包含同一个对象)你可以考虑通过智能指针(共享或唯一)在队列本身或某处存储动态分配的对象否则,您将确保您的队列不包含悬挂指针。