在Vector c ++中使用指针成员初始化对象

时间:2015-03-14 17:59:54

标签: c++ pointers vector constructor deep-copy

当我使用push_back()方法时,我希望能够在对象上调用非平凡的构造函数。相反,我所能做的就是将对象的浅表副本传递给向量。使用常规c样式数组时,在创建数组时会自动调用构造函数,但由于向量是动态的,因此该对象尚不存在。

如何在不将两个指针指向同一内存地址的情况下向向量添加新的空对象?我需要复制构造函数或重载赋值运算符吗?

以下是一些演示我问题的示例代码:

struct Object
{
    int *Pointer;

    Object()
    {
        Pointer = new int;
        *Pointer = 42;
    }

    ~Object()
    {
        delete Pointer;
    }
};


int main()
{
    std::vector <Object> *Array;
    Array = new std::vector <Object>;

    // Attempt 1
    Array->push_back(Object());

    // Attempt 2
    {
        Object LocalInstance;
        Array->push_back(LocalInstance);
    }

    // Error here because the destructor has already been called for 
    // LocalInstance and for Object()
    delete Array;

    return 0;
}

1 个答案:

答案 0 :(得分:1)

@KonradRudolph是正确的 - Array没有理由成为这里的指针,它只是模糊了代码。

您的代码崩溃的原因是因为LocationInstance传递给push_back,但您的Object没有正确的复制构造函数,因此只复制Pointer成员的浅层副本。当LocalInstance超出范围时,该对象将删除其Pointer,但容器中的副本具有相同的Pointer,这会导致在清理容器时删除释放的内存。

请查看Rule-of-Five(在C ++ 11之前是规则三)。

在将构建对象添加到容器时,对于构造对象,您使用的是C ++ 11吗?如果是这样,您可以emplace_back并在添加容器时构建容器 - 您正在寻找的是什么?

这个简单的例子只给我一个警告:

struct A
{
    A(int a) : member_m(a)
    {}

    int &member_m;
};
int main() {
    A a(1);
}

给了我:

~/ClionProjects/so_reference_to_temporary $ clang++ -o test main.cpp
main.cpp:8:25: warning: binding reference member 'member_m' to stack allocated
      parameter 'a' [-Wdangling-field]
    A(int a) : member_m(a)
                        ^
main.cpp:13:10: note: reference member declared here
    int &member_m;
         ^
1 warning generated.