用于在C++中初始化的memset

sky*_*oor 16 c++

memset有时用于在构造函数中初始化数据,如下例所示.它一般有效吗?一般来说这是个好主意吗?

class A {
public:
   A();
private:
   int a;
   float f;
   char str[35];
   long *lp;
};

A::A()
{
   memset(this, 0, sizeof(*this));
}
Run Code Online (Sandbox Code Playgroud)

rlb*_*ond 22

不要用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)
{
}
Run Code Online (Sandbox Code Playgroud)

说实话,我不确定,但memset浮点数可能也不错,因为它们的格式没有说明.


GMa*_*ckG 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));
Run Code Online (Sandbox Code Playgroud)

但是如果你正在进行this,那意味着你在一个用户定义的构造函数中,不再符合POD类型.(虽然如果所有成员都是POD,它可能会起作用,只要没有包含0作为陷阱值.我肯定不确定是否有任何其他未定义行为来源在这里发挥作用.)

  • @STingRay:对不起,我的意思是用户定义的构造函数.拥有用户定义的构造函数(如OP所具有的)意味着它不是聚合,因此不是POD.注意我在课外调用`memset`.在构造函数中调用它会自动意味着它不是POD类型,因为我已经定义了一个构造函数. (2认同)