Как говорят другие, memset()
- неправильный способ сделать это.
Однако есть некоторые тонкости, почему нет.
Во-первых, ваша попытка использовать memset()
очищает только sizeof(void *)
байт. В нашем примере это, по-видимому, совпадение байтов, занятых элементом x
.
Простым решением было бы написать memset(this, 0, sizeof(*this))
, который в этом случае установил бы x
и y
.
Однако, если в вашем классе vector2
есть какие-либо виртуальные методы и обычный механизм используется для их представления вашим компилятором, тогда этот memset
уничтожит vtable
и сломает экземпляр, установив указатель vtable
в NULL. Что плохо.
Другая проблема состоит в том, что если для типа T
требуется какое-либо более сложное действие конструктора, чем просто установка его битов в 0, то конструкторы для элементов не вызываются, но их эффект разрушается перезаписью содержание членов с memset()
.
Единственное правильное действие - написать конструктор по умолчанию как
vector2(): x(0), y(0), {}
и просто забыть о попытке использовать memset()
для этого вообще.
Edit: D.Shawley указал в комментарии, что конструкторы по умолчанию для x
и y
действительно были вызваны до memset()
в исходном коде, как представлено. Хотя это технически верно, вызов memset()
перезаписывает участников, что в лучшем случае действительно, очень плохая форма, а в худшем случае вызывает демонов Неопределенного поведения.
Как написано, класс vector2
- это POD, если тип T
также является обычными старыми данными, как если бы T
были int
или float
.
Однако все, что нужно для того, чтобы T
был своего рода классом значения bignum
, вызывать проблемы, которые действительно трудно диагностировать. Если вам повезет, они начнут проявляться на ранних этапах через нарушения прав доступа из-за разыменования указателей NULL, созданных memset()
. Но Lady Luck - непостоянная любовница, и более вероятным результатом будет утечка памяти, и приложение становится «шатким». Или, скорее, «потряснее».
ОП спросил в комментарии к другому ответу: "... Есть ли способ заставить memset работать?"
Ответ прост: «Нет».
Выбрав язык C ++ и полностью воспользовавшись шаблонами, вы должны заплатить за эти преимущества, правильно используя язык. Просто не правильно обходить конструктор (в общем случае). Хотя существуют обстоятельства, при которых законно, безопасно и разумно вызывать memset()
в программе на C ++, это просто не один из них.