3

我正在研究一个相当大的 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>());

但是,程序因调试错误而终止:向量迭代器不兼容。它发生在这个任务上:

m_data = data;

...应该制作一个副本,这是我打算做的。

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

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

...一切都按预期工作。

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

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

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

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) 的构造函数也从未被执行过。这就是为什么在隐式调用复制函数崩溃时分配构造函数起作用的原因,因为尚未构造目标向量。好的经验教训和更可怕的代码需要改进:)

谢谢!

4

3 回答 3

3

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

但是,有更好的方法来进行初始化:

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;
};
于 2012-04-05T09:20:54.113 回答
1

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

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;

};
于 2012-04-05T09:22:01.513 回答
0

是否调用:

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

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

于 2012-04-05T09:22:13.930 回答