我想将派生结构体的所有成员归零。
有数百个成员,而且每过一段时间就会添加更多的成员,所以我觉得显式初始化它们很容易出错。
结构体没有虚函数,所有成员字段都是内置的。但是,它们不是POD,因为它们具有非平凡的构造函数。
除了对实践的标准不满之外,您认为以下方面有什么问题吗?
struct Base
{
// Stuff
};
struct Derived : public Base
{
// Hundreds of fields of different built-in types
// including arrays
Derived()
{
::memset(reinterpret_cast<char*>this + sizeof (Base), 0, sizeof *this - sizeof (Base));
}
};
谢谢。
假设Base
基类子对象位于Derived
的开头。如果您添加另一个基类,这将不起作用。
此外,你的代码是错误的:指针算术是按对象执行的,而不是按字节执行的。您需要使用reinterpret_cast<char*>(this)
来执行以字节为单位的算术。无论如何,你还是不应该这样做。
考虑以下使用值初始化的非丑陋的、符合标准的方法:
struct Derived : public Base
{
struct DerivedMembers { /* ... */ }
DerivedMembers data;
Derived() : data() { }
};
只要DerivedMembers
没有构造函数,这将值初始化data
的每个数据成员,这看起来正是您想要的行为。
或者,如果您希望在不使用" data
"成员变量的情况下可以访问成员,请考虑使用另一个基类:
struct DerivedMembers { /* ... */ }
struct Derived : Base, DerivedMembers
{
Derived() : DerivedMembers() { }
};
你不应该这样做。您应该在每个类中使用初始化列表,以避免必须这样做。在第一轮中完成它将是一件很忙的工作,但是如果之后遵循实践,它就微不足道了。
参见类似的问题:
您应该显式地将所有值设置为零,而不要使用memset,因为这是不可移植的。编译器/内存分配可能存储有您可能会覆盖的日常数据。
标准不"不赞成实践";它给出未定义的行为。
例如:this + sizeof (Base)
c++标准中没有规定这个表达式解析为指向Derived的指针。实际上,由于this
的类型是Derived * const
,那么您所做的就是指针算术。c++将尝试将this
添加为指向Derived
(相当于this[sizeof(Base)]
)数组的指针。这可能不是你想要的。
如果你不确定如何正确地做这件事,就不要走未定义行为的黑暗走廊。
最重要的是,即使你的指针体操实际工作,你的代码变得非常脆弱。它可能在这个版本的编译器上工作,但在以后的版本上就会失败。做一些简单的事情,比如在 我觉得你有几个问题:Base
中添加一个虚函数,将导致代码中的混乱,因为您将破坏虚函数表指针。
成员,那么它可能做得太多了。 Base
没有任何虚拟的东西,你为什么要公开派生它?