c++ - 如何在 C++ 中正确地推回 vector 中的一系列对象?

标签 c++

该程序的范围是创建一个 Container 对象,该对象存储在一个 vector Class 对象中。然后我想打印,从 vector 的所有前辈的精确类对象开始。

class Class{
public:
    Class(){
        for (int i = 0; i < 10; ++i) {
            Class c;
            c.setName(i);
            if (i > 0) {
                c.setNext(_vec,i-1);
            }
            _vec.push_back(c);
        }
    }   
};
    ~Class();
    void setName(const int& n);
    void setNext( vector<Class>& vec, const int& pos);
    Class* getNext();
    string getName();
    void printAllNext(){ //print all next Class objects including himself
        cout << _name <<endl;
        if (_next != nullptr) {
            (*_next).printAllNext();
        }
    }
private:
    Class* _next;
    string _name;
};

class Container{
public:
    Container(){
         for (int i = 0; i < 10; ++i) {
               Class c;
               c.setName(i);
               if (i > 0) {
                   c.setNext(_vec,i-1);
               }
         _vec.push_back(c);
    };
    ~Container();
    void printFromVec(const int& n){//print all objects of _vec starting from n;
    _vec[n].printAllNext();
    }; 
private:
    vector<Class> _vec;
};

int main() {

    Container c;
    c.printFromVec(5);
}

问题是 Class 对象的所有 _next 指针都是未定义的或随机的。 我认为问题在于这部分代码:

class Container{
public:
    Container(){
         for (int i = 0; i < 10; ++i) {
               Class c;
               c.setName(i);
               if (i > 0) {
                   c.setNext(_vec,i-1);
               }
         _vec.push_back(c);
    };

调试我注意到已经创建的对象的指针改变了它们的值。 问题是什么?我怎样才能让它发挥作用?

最佳答案

虽然代码中确实存在错误(可能是错误的复制粘贴),但问题确实如下:std::vector 维护在动态分配的对象数组中。它以一定的初始大小开始。当您推送到 vector 时,它会填充数组的条目。当所有条目都已填满但您尝试推送更多元素时,vector 会分配更大的内存块并将对象移动或复制(无论您支持哪种元素数据类型)到新的内存位置。这就是对象地址发生变化的原因。

现在谈谈该怎么做。

解决方案 1. 使用 std::list 而不是 std::vectorstd::list是双向链表,元素一旦加入链表,就是链表项的一部分,不会改变它的地址,没有重新分配。

解决方案 2. 使用共享指针 vector 。在这种情况下,您需要动态分配每个对象并将地址放入共享指针对象中,您可以使用函数 std::make_shared() 同时完成这两项工作。然后将共享指针推送到 vector ,并将 std::weak_ptr 存储为指向上一个/下一个的指针。

解决方案 3。如果您知道 vector 中可能拥有的最大元素数,您可以保留所有元素,但在第一次推送之前做一件额外的事情 - 调用 reserve()以最大元素数作为参数的 vector 。 Vector 将分配该大小的数组并保留它,直到它被填满并且需要更多空间。但是由于您分配了您期望拥有的最大可能大小,因此永远不会发生重新分配,因此对象的地址将保持不变。

选择您认为最适合您需求的解决方案。

关于c++ - 如何在 C++ 中正确地推回 vector 中的一系列对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56918035/

相关文章:

c++ - 具有 NDK 和大量 C++ 依赖项的 Android Studio 2.3.3 项目卡在 `Building symbols`

c++ - 将大量数字 vector 保存到硬盘驱动器

c++ - C++ 中的智能指针与共享对象验证

c++ - 不同类型和不同编译器的 std::isinf 的不同结果

c++ - std::map 的底层结构是什么?

c++ - Clang 看不到 strdup 和其他一些函数

c++ - 返回类型是实例化的还是简单分配的值

C++ - 类声明中的两个名称(宏)

c++ - 线程安全的 std::map:锁定整个映射和单个值

c++ - 来自片段着色器中 GL_TEXTURE_1D 的样本