memset有时用于在构造函数中初始化数据,如下例所示。它一般有效吗?一般来说这是一个好主意吗?
class A {
public:
A();
private:
int a;
float f;
char str[35];
long *lp;
};
A::A()
{
memset(this, 0, sizeof(*this));
}
答案 0 :(得分:21)
请勿使用memset
。这是C的保留,不适用于非POD。具体来说,在包含任何虚函数的派生类(或包含非内置函数的任何类)上使用它将导致灾难。
C ++为初始化提供了特定的语法:
class A {
public:
A();
private:
int a;
float f;
char str[35];
long *lp;
};
A::A()
: a(0), f(0), str(), lp(NULL)
{
}
老实说,我不确定,但memset
对于浮点也可能是一个坏主意,因为它们的格式未指定。
答案 1 :(得分:12)
这是一个糟糕的主意。你只是在操纵数据,不注意如何初始化对象。如果你的类是虚拟的,你也可能会消灭vtable指针。
memset
适用于原始数据,但C ++与原始数据无关。 C ++创建抽象,所以如果你想要安全,你可以使用那些抽象。使用初始化列表初始化成员。
您可以对POD类型执行此操作:
struct nothing_fancy_here
{
bool b;
int i;
void* p;
};
nothing_fancy_here x;
memset(&x, 0, sizeof(x));
但如果你在this
上进行,那意味着你在用户定义的构造函数中,不再符合POD类型。 (虽然如果所有成员都是POD,它可能会起作用,只要没有包含0作为陷阱值。我肯定不确定是否有任何其他未定义行为的来源在这里发挥作用。)