【问题标题】:Vector member is lost while managing a queue of the class pointers C++在管理类指针 C++ 的队列时,向量成员丢失
【发布时间】:2020-09-28 17:54:49
【问题描述】:

我有一个名为 AClass 的非常简单的类,它有两个成员:一个 int 和一个 int 向量。在我的程序中,我试图使用指向该类对象的指针队列和该队列上的 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 循环中创建的对象的向量不会打印任何内容。它的大小为零。

【问题讨论】:

  • 为什么是指针?并且对于局部变量也不少..

标签: c++ class pointers vector member


【解决方案1】:

您的程序由于指向本地对象的悬空指针而表现出未定义行为,该对象的生命周期以该对象在其中创建的块结束(在您的情况下为while 循环)。在您的情况下,最简单的解决方案是按值而不是按指针存储对象,并让 std::queue 正确管理对象的生命周期。在更复杂的场景中(比如您不想移动/复制对象,或者队列可以多次包含同一个对象),您可以考虑通过智能指针(共享或唯一)将动态分配的对象存储在队列本身或其他地方,这样您将确保您的队列不包含悬空指针。

【讨论】:

  • 是的,我的目标是避免像在我的实际代码中那样按值存储对象,这些对象可能相对较大。
  • @user1253514 按值存储它们并不强制降低效率,你错了,但可能有其他原因通过指针存储它们(智能与否)。
【解决方案2】:

while 循环中,您正在添加指向队列的指针,该指针指向局部变量的地址。在循环的下一次迭代中,该变量死亡,并且您拥有的指针不再有效。

添加到队列中的第一个指针是在main 期间存在的对象的地址,因此该指针是有效的。

可以为添加到队列中的指针分配内存。但是,如果您选择走那条路,您应该更喜欢使用 std::unique_ptr 之类的东西,而不是原始指针。

【讨论】:

  • 啊,我明白了,我怀疑这是变量超出范围的问题,但我可以访问正确的 int 成员这一事实令人困惑。此外,关于 std::unique_ptr,这将允许它指向的对象持续存在,但我现在将负责在某个时候删除它。对吗?
  • @user1253514 UB 在简单的情况下可以“似乎工作”
  • @user1253514 “另外,关于std::unique_ptr,这将允许它指向的对象持续存在,但我现在将负责在某个时候删除它。对吗? ?" 不,请查阅一些文档:unique_ptr 将在超出范围时为您删除该东西
  • 访问int 也是UB,尽管它似乎有效。不,unique_ptr 的全部意义在于避免手动删除任何内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-02
  • 1970-01-01
相关资源
最近更新 更多