C++ 是不是对 POD typedef 进行值初始化?

Posted

技术标签:

【中文标题】C++ 是不是对 POD typedef 进行值初始化?【英文标题】:Does C++ do value initialization of a POD typedef?C++ 是否对 POD typedef 进行值初始化? 【发布时间】:2009-05-25 13:23:43 【问题描述】:

C++ 是否对简单的POD typedefs 进行值初始化?

假设

typedef T* Ptr;

Ptr()

做值初始化并保证等于(T*)0?

例如

Ptr p = Ptr();
return Ptr();

【问题讨论】:

【参考方案1】:

确实如此。对于T 类型,T() 值初始化T 类型的“对象”并产生一个右值表达式。

int a = int();
assert(a == 0);

对于 pod 类也是如此:

struct A  int a; ;
assert(A().a == 0);

对于一些没有用户声明的构造函数的非 POD 类也是如此:

struct A  ~A()   int a; ;
assert(A().a == 0);

由于你不能做A a()(而是创建一个函数声明),boost 有一个类value_initialized,允许解决这个问题,C++1x 将具有以下替代语法

int a;

用标准的干巴巴的话来说,这听起来像

表达式 T(),其中 T 是非数组完整对象类型或(可能是 cv 限定的)void 类型的简单类型说明符 (7.1.5.2),创建指定类型的右值,这是值初始化的

因为 typedef-name 是一个 type-name,它本身就是一个简单的类型说明符,这很好用。

【讨论】:

我一直在研究标准草案,试图弄清楚这一点。我忘记了 typedef 并试图弄清楚指针类型如何成为简单类型说明符(它不是),现在它是有道理的:你不能做 int*(),但你可以做T() 如果 T 被定义为 int*。 非 POD 类型和 POD 成员呢? 结构 A ~A() int a; ;是非 pod 类型。如果你自己引入了构造函数,那么“a”的值当然取决于构造函数的作用。【参考方案2】:
#include <iostream>
struct Foo 
    char bar;
    char baz;
    char foobar;
    // the struct is a POD
    //virtual void a()  bar='b'; 
;

int main() 
    Foo o1;
    Foo o2 = Foo();

    std::cout << "O1: " << (int)o1.bar <<" "<< (int)o1.baz <<" "<< (int)o1.foobar << std::endl;
    std::cout << "O2: " << (int)o2.bar <<" "<< (int)o2.baz <<" "<< (int)o2.foobar << std::endl;
    return 0;

输出:

O1:-27 -98 0

氧气:0 0 0

添加 () 会将初始化程序调用传播到所有 POD 成员。取消注释虚拟方法会将输出更改为:

O1:-44 -27 -98

氧气:-71 -120 4

但是添加析构函数 ~Foo() 不会抑制初始化,尽管它会创建非 POD 对象(输出类似于第一个)。

【讨论】:

以上是关于C++ 是不是对 POD typedef 进行值初始化?的主要内容,如果未能解决你的问题,请参考以下文章

C++中的typedef和using

C ++检查是不是定义了typedef [重复]

C++ typedef详解

重复的 typedef - 在 C 中无效但在 C++ 中有效?

C++ 静态多态性 (CRTP) 和使用派生类的 typedef

我啥时候应该在 C++ 中使用 typedef?