可以在不调用 memset 的情况下从构造函数初始化器列表中将成员结构设为零吗?

Posted

技术标签:

【中文标题】可以在不调用 memset 的情况下从构造函数初始化器列表中将成员结构设为零吗?【英文标题】:Can a member struct be zero-init from the constructor initializer list without calling memset? 【发布时间】:2010-05-12 07:27:47 【问题描述】:

假设我有以下结构声明(没有构造函数的简单结构)。

struct Foo

    int x;
    int y;
    int z;
    char szData[DATA_SIZE];
;

现在假设这个结构是一个 C++ 类的成员,如下所示:

class CFoobar

     Foo _foo;
public:
     CFoobar();
;

如果我声明CFoobar的构造函数如下:

CFoobar::CFoobar()

    printf("_foo = %d, %d, %d\n", _foo.x, _foo.y,_foo.z);
    for (int x = 0; x < 100; x++)
       printf("%d\n", _foo.szData[x]);

如你所料,当 CFoobar 的构造函数运行时,垃圾数据被打印出来显然,简单的修复是 memset 或 ZeroMemory &_foo。这是我一直做的......

但是,我确实注意到如果将 _foo 添加到不带参数的构造函数的初始化列表中,如下所示:

CFoobar::CFoobar()
: _foo()

这似乎将 _foo 的成员变量清零。至少 linux 上的 g++ 是这样的。

现在我的问题是:这是标准 C++,还是编译器特有的行为?

如果这是标准行为,有人可以从官方来源引用我的参考吗?对于更复杂的结构和类的隐式零初始化行为有任何“陷阱”吗?

【问题讨论】:

【参考方案1】:

是的,这是根据标准定义的行为。 12.6.2 [class.base.init] / 3 : "如果mem-initializerexpression-list被省略,则基类或成员子对象为值初始化。”

但请注意,如果 Foo 不是 POD 类型但仍然没有用户声明的构造函数(例如,它有 std::string 类型),那么一些非常流行的编译器将无法正确 value-初始化它。

当您使用 () 作为构造函数初始化器列表中的初始化器时,我所知道的所有编译器都会正确执行 POD 成员的值初始化

【讨论】:

"一些流行的编译器" = VC6 我假设?因为在过去的 10 年里,我没有在任何编译器中看到错误的行为。 @MSalters:不幸的是,还有 VS2005 和 VS2008 编译器。我没有在 VS2010 上尝试过。 @MSalters:它不仅适用于没有用户声明的构造函数的非 POD 结构成员;其他类型正常工作。 Connect上有几篇关于此的报道。这是我找到的:connect.microsoft.com/VisualStudio/feedback/details/484295/… 我的意思是“注意,它只适用于...”,而不是“不只是...”,但为时已晚,无法编辑。还有,即使VC6很流行我也会一针见血的拒绝承认这个事实。 :) 啊哈,至少还有一个附加标准(存在基类)。这或许可以解释为什么我没有注意到。【参考方案2】:

我觉得阅读标准很难,但我认为:

对 T 类型的对象进行值初始化意味着: 如果 T 是没有用户声明的构造函数的非联合类类型,则每个非静态数据成员和基类 T 的类组件是值初始化的 这种类对象的值初始化可以通过对对象进行零初始化,然后调用默认构造函数来实现。

第 8.5 节

【讨论】:

8.5 需要与 12.6.2 一起阅读才能知道这个成员初始化器确实需要 value-initialization【参考方案3】:

相当于float foo = float();

它会将对象归零,即使值表示不是全位为零。 IE。比memset()还要好。

【讨论】:

以上是关于可以在不调用 memset 的情况下从构造函数初始化器列表中将成员结构设为零吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用表单的情况下从 jsp 调用 servlet

在不使用 COM 的情况下从 C++ 调用 C# 方法

如何在不破坏内部绑定的情况下从外部初始化自定义项的属性?

如何在不使用复合文字的情况下从标量初始化 AltiVec 寄存器

在不事先了解特定成员函数的情况下从另一个类访问成员函数

在不调用构造函数的情况下创建 Vector 元素