使用memset这种方式很好吗?

时间:2014-03-25 11:17:50

标签: c++ memset

我用这种方式使用memset:

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

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

我应该用这种方式吗?为什么不呢?有没有更好的办法?需要一些指导..

4 个答案:

答案 0 :(得分:9)

这通常是一个坏主意。

如果有人在课程中添加新成员,如果新成员的类型具有正确的构造函数并且memset不合适,则可能会破坏。

正式地,根据标准,您的用户定义构造函数意味着A不是POD类型(或C ++ 11中的易于复制的类型),因此使用{{1}是不安全的或memset就可以了。

有几种方法可以安全地执行此操作:

memcpy

或者,不要添加构造函数和值初始化类型的实例:

A::A() : a(), f(), str(), lp()
{ }

或者,将POD成员分组在一起,并在构造函数中一次对它们进行值初始化:

A a = A();

一般来说,最好在C ++中使用值初始化,并依赖编译器执行等效的class A { public: A(); private: struct Data { int a; float f; char str[35]; long *lp; }; Data data; }; A::A() : data() { } (或调用默认构造函数),而不是自己使用memset。代码将不那么脆弱且易于维护。

答案 1 :(得分:2)

你现在可以侥幸逃脱。即使你的类不是POD(它有一个自定义构造函数),实际上大多数实现都会做'正确的TM',只要你不从你的类继承。所以最好不要这样做。但要注意,所有位零都不能保证是NULL指针也不是浮点0.0。

如果你想要一个初始化的POD,那么只需定义变量:

POD_T my_var = {};

C ++将自动使用最有效的初始化。

如果您不想要POD,请使用构造函数的初始化列表,让编译器为您进行优化。

A::A() : a(), f(), str(), lp() { }

答案 2 :(得分:0)

这篇文章以及关于C ++对象内存模型的一般内容已在Stanley B. Lippman的“Inside the c ++ object model”一书中得到了很好的解释。

然而,只有在类不包含时,才使用memcpy()和memset() 任何编译器生成内部成员。而C ++对象模型尚未定义 标准如此不同的编译器可以自由实现,因此我们永远不能100%依赖 编译器是否已生成/插入内部成员(VPTR最常见)。

他已经使用具有虚函数类型成员的类来解释它(对于这样的类编译器插入VPTR)。

A::A()
{
    // vptr must be set before user code executes
    __vptr__A = __vtbl__A;
    // oops: memset zeros out value of vptr
    memset( this, 0, sizeof(A));
};

因此,即使在某些情况下效率更高,这也不是一个好主意。

答案 3 :(得分:-1)

尝试以下代码

memset(this, 0, sizeof(A));