目前在我的DirectX游戏上工作并在常量缓冲区构造函数中使用memset(0)(或VS中的ZeroMemory宏)来初始化所有带零的值,它可以正常工作。当我意外地尝试以这种方式初始化包含向量的其他结构时出现问题。根据编译器(VS2010 / VS2012),这会导致“矢量迭代器不兼容”,std :: vector :: end更加精确。我可以理解memset可能会使向量迭代器无效,但是在我将元素推回到向量之后,为什么“结束”迭代器无法正常工作。它不应该重新定位向量将迭代器结束到正确的位置(在最后一个元素之后)?所有类型的std :: some_container :: end迭代器都受此影响吗?
#include <vector>
class MyClass
{
public:
MyClass() {
memset(this, 0, sizeof(*this));
}
~MyClass() {}
std::vector<int>& GetData() { return m_data; }
float m_range;
private:
std::vector<int> m_data;
};
int main()
{
MyClass myClass;
myClass.GetData().push_back(1);
myClass.GetData().push_back(2);
for (auto it = myClass.GetData().begin(); it != myClass.GetData().end(); it++)
{
//stuff
}
}
答案 0 :(得分:7)
std::vector
已经有一个默认构造函数,可以正确初始化向量。什么都不做就有你想要的行为。使用memset
只是具有未定义的行为。
如果要将float
成员初始化为零,C ++会为此提供如下代码:
MyClass() : m_range(0) {}
C ++ 11还允许编写float m_range = 0;
,但Microsoft的编译器尚未实现此功能。
mem*
函数是非常粗糙的工具,在std::vector
等C ++构造中没有位置。正确初始化,std::copy
和std::fill
等替代方案是优秀的解决方案,因为它们不会践踏类型系统。
答案 1 :(得分:3)
你不应该memset
构造函数的任何类对象。
答案 2 :(得分:2)
请改为:
class MyClass {
public:
MyClass() : range{} {
}
float range;
std::vector<int> data;
};
永远不要使用memset
,绝对不能使用this
哦上帝。
专业提示:buy a good book。
答案 3 :(得分:0)
你的对象是在memset之前构造的,它会导致问题。
以这种方式初始化对象在C ++中不是一个好方法