[英]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中的普通可复制类型),因此在上面使用memset
或memcpy
是不安全的。
有几种方法可以安全地执行此操作:
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.