В настоящее время работаю над моей игрой DirectX и использую memset (0) (или макрос ZeroMemory в VS, если хотите) в конструкторах константных буферов, чтобы инициализировать все значения нулями, и это прекрасно работает. Проблема возникает, когда я случайно попытался инициализировать другую структуру, содержащую вектор, таким образом. Согласно компилятору (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
}
}
std::vector
уже есть конструктор по умолчанию, который правильно инициализирует вектор. Бездействие — это поведение, которое вы хотите. С помощью memset
просто имеет неопределенное поведение.
Если вы хотите инициализировать float
член к нулю, C ++ обеспечивает это с помощью кода, подобного следующему:
MyClass() : m_range(0) {}
C ++ 11 также позволяет писать float m_range = 0;
, но компилятор Microsoft пока не реализует эту функцию.
mem*
функции — это очень грубые инструменты, которым нет места среди конструкций C ++, таких как std::vector
, Альтернативы, такие как правильная инициализация, std::copy
, а также std::fill
являются превосходными решениями, потому что они не попирают систему типов.
Ты не должен быть memset
Любые объекты классов с конструкторами.
Сделайте это вместо этого:
class MyClass {
public:
MyClass() : range{} {
}
float range;
std::vector<int> data;
};
Никогда не используйте memset
и, конечно, абсолютно не на this
О Боже.
Pro совет: купить хорошую книгу.
Ваш объект создается перед memset, что вызывает проблемы.
Инициализация объекта таким способом не является хорошим подходом в C ++