C++ C+中初始化的memset+;

C++ C+中初始化的memset+;,c++,C++,memset有时用于初始化构造函数中的数据,如下例所示。一般情况下有效吗?总的来说,这是个好主意吗 class A { public: A(); private: int a; float f; char str[35]; long *lp; }; A::A() { memset(this, 0, sizeof(*this)); } 这是个糟糕的主意。您只是在数据上跑来跑去,根本不考虑对象应该如何初始化。如果您的类是虚拟的,那么很可能也会删除vtable指

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

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

A::A()
{
   memset(this, 0, sizeof(*this));
}

这是个糟糕的主意。您只是在数据上跑来跑去,根本不考虑对象应该如何初始化。如果您的类是虚拟的,那么很可能也会删除vtable指针

<代码> MyStuts<代码>在原始数据上工作,但C++不是原始数据。C++创建抽象,所以如果你想安全,你就使用这些抽象。使用初始值设定项列表初始化成员

您可以对POD类型执行此操作:

struct nothing_fancy_here
{
    bool b;
    int i;
    void* p;
};

nothing_fancy_here x;
memset(&x, 0, sizeof(x));

但是如果你在
这个
上做这件事,那就意味着你在一个用户定义的构造函数中,不再符合POD类型的资格。(尽管如果您的所有成员都是POD,它可能会工作,只要没有一个包含0作为陷阱值。我不确定这里是否有其他未定义行为的来源。)

不要使用
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
可能对浮点也是个坏主意,因为它们的格式没有指定。

您的
nothing\u fancy\u这里的
类型也有构造函数吗?我不认为你所说的吊舱类型和OPs示例类之间有什么区别。。。您是否从构造函数中调用
memset
,与此无关。如果在你的例子中没有问题,那么在OP中也没有问题。@STingRay:它没有构造函数。可能
/…
太开放了。它确实有一个构造函数。假设它是一个不可操作的。关于是否有显式声明的构造函数的问题无关紧要。正如您所说,重要的是结构/类(或其任何成员类型)是否具有虚拟成员函数。如果OP没有像您那样声明构造函数并调用
memset
,那么就没有什么区别了。因此,最终的答案是:在给定的示例中,从技术上讲,这样做是可以的,但作为一般实践,当然不是…@STingRay:对不起,我指的是用户定义的构造函数。拥有一个用户定义的构造函数,就像OP一样,意味着它不是一个聚合,因此也不是一个POD。注意,我正在课外调用
memset
。在构造函数中自动调用它意味着它不是POD类型,因为我已经定义了一个构造函数。
谢谢你让另一个问题保持活跃。这比我希望的要复杂一些。还有
std::fill
std::fill\n
如果您需要为数组案例“memset”数组(或任何其他序列),那么最好执行
str()
。GCC在通过成员初始值设定项通过字符串文本初始化字符数组时遇到问题,如果数组不是字符数组,则即使在符合标准的编译器中也无法工作
str()
将始终使数组为空。(我刚刚提交了一份bug报告:)@litb:上面已经注意到并更改了。您可以使用以下方法: