将空向量传递给对象的"correct"方法是什么?

What's the "correct" way to pass an empty vector to an object?

本文关键字:correct 方法 是什么 对象 向量      更新时间:2023-10-16

我正在处理一个相当大的C++项目,不幸的是,该项目并没有充分利用C++的潜力。大部分代码仍然是用荒谬的C++类包装的普通C。

因此,我试图通过引入一些C++和STL来使代码更可读、更安全。

然而,当我将向量分配给对象成员时,我会遇到一个奇怪的崩溃(确切地说是调试错误)。想象一下:

class A
{
public:
    // Default constructor
    A()
    {
        initialize(std::vector<unsigned long>());
    };
    A(const std::vector<unsigned long> &data)
    {
        initialize(data)
    };
    ~A() {};
    void initialize(const std::vector<unsigned long> &data)
    {
        m_data = data;
    };
private:
    std::vector<unsigned long> m_data;
};

然后在代码的其他地方,我调用:

a.initialize(std::vector<unsigned long>());

但是,由于调试错误,程序终止了du:矢量迭代器不兼容。它发生在这个任务上:

m_data = data;

这应该是一个副本,这就是我打算做的。

但是,如果我将此行更改为:

m_data = std::vector<unsigned long>(data);

一切如预期。

我的问题是:为什么?这是用空向量初始化对象的正确方法吗

请记住,这个类实际上要大得多,传递的成员也要多得多,这就是我使用initialize函数的原因。还有一种可能性是传递一个已经存在的数组,所以我确实需要能够将其初始化为空或使用现有数据。

编辑:我已经找到了车祸的原因。我发现我正在查看的代码实际上有点不同:

A *pA = malloc(...); // Not really malloc but a wrapper for a WINAPI-Alloc
// Some stuff happens in between
pA->initialize(std::vector<unsigned long>());

事实上,A的构造函数从未被调用过,因此向量成员(m_data)的构造函数也从未被执行过。这就是为什么在隐式调用复制函数时分配构造函数有效的原因,因为目标向量还没有构造好。这是一个教训,更可怕的代码需要改进:)

谢谢!

我不知道为什么您的代码会因该错误而崩溃,因为从表面上看,它看起来还可以。也许您应该编辑您的问题,以包含一个最小的测试用例。

然而,有更好的方法来进行初始化:

class A
{
public:
    // Default constructor.
    // Relies on the fact that the default constructor for std::vector is
    // an empty vector.
    A()
    {}
    // Use the initialisation list.
    A(const std::vector<unsigned long> &data)
    : m_data(data)
    {}
private:
    std::vector<unsigned long> m_data;
};

std::vector构造函数已经初始化了一个空向量。如果您想从另一个std::向量中分配数据,可以使用复制构造函数。

class A
{
public:
    // Default constructor
    A()
    {
        // Not required:
        // initialize(std::vector<unsigned long>());
    }
    // Make it explicit
    explicit A(const std::vector<unsigned long> &data)
      : m_data(data) // vector copy ctor
    {
    }
    ~A() {}

private:
    std::vector<unsigned long> m_data;
};

是否调用:

a.initialize(std::vector<unsigned long>());

在不同于定义A的库中?在这种情况下,我猜其中一个库是在启用调试迭代器的情况下构建的,而另一个库则没有。