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 进行值初始化?的主要内容,如果未能解决你的问题,请参考以下文章
重复的 typedef - 在 C 中无效但在 C++ 中有效?