繁体   English   中英

用memset这样好吗?

[英]Using memset this way is good?

我这样使用memset:

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

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

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

这通常是一个坏主意。

如果有人将新成员添加到类中,则如果新成员的类型具有适当的构造函数且memset不适合,则可能会严重中断。

正式地,根据标准,用户定义的构造函数意味着A不是POD类型(或C ++ 11中的普通可复制类型),因此在上面使用memsetmemcpy是不安全的。

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

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

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

A a = A();

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

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

A::A() : data()
{ }

通常,最好在C ++中使用值初始化,并依靠编译器执行与memset等效的操作(或调用默认构造函数),而不是自己专门使用memset 该代码将不那么脆弱,更易于维护。

您可能暂时不使用它。 即使您的类不是POD(它具有自定义构造函数),实际上,只要您不从类继承,大多数实现都将执行“正确的TM”。 所以最好不要这样做。 但是请注意,不能保证所有零位都是NULL指针或浮点数0.0。

如果要初始化POD,只需定义变量即可:

POD_T my_var = {};

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

如果您不需要POD,请使用构造函数的初始化程序列表,然后让编译器为您优化。

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

Stanley B. Lippman“ Inside the c ++ object model”一书中很好地解释了关于C ++对象内存模型的一般知识。

但是,仅在类不包含任何编译器生成的内部成员的情况下,才使用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));
};

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

尝试以下代码

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM