我正在开发一个相当大的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)的构造函数也从未执行过。这就是为什么在隐式调用复制函数崩溃时分配构造函数的原因,因为目标向量尚未构造。好的经验教训和更可怕的代码改进:)
谢谢!
答案 0 :(得分:3)
我不知道为什么你的代码崩溃了,因为它看起来不错,表面上看起来不错。也许您应该修改问题以包含minimal test case。
但是,有更好的方法可以进行初始化:
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;
};
答案 1 :(得分: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;
};
答案 2 :(得分:0)
是电话:
a.initialize(std::vector<unsigned long>());
在与定义A
的库不同的库中?在这种情况下,我猜其中一个库是在启用调试迭代器的情况下构建的,而另一个库则不是。