2011-05-10 73 views
4

我有这样的片段:奇怪的C++代码片段

template<class T> 
class VECTOR_2D 
{ 
public: 
    T x,y; 

    VECTOR_2D() 
     :x(T()),y(T()) 
    {} 
} 

什么是X和Y在构造函数初始化?

+2

这不是“怪异”。 – 2011-05-10 12:41:40

+0

unwind的答案是正确的,顺便说一下,没有必要像这样将x和y包含在VECTOR_2D的构造函数列表的初始化列表中,因为它们将自动由其默认构造函数初始化。 – DataGraham 2011-05-10 12:43:49

+2

@DataGraham:你错了。如果'T'是一个原语,并且你没有明确地初始化它们,它们将保持未初始化。 – 2011-05-10 12:45:10

回答

6

xy副本初始化T值初始化值。

从C++ 03标准,第8.5节/ 7:

其初始化为空集括号的一个目的,即(),应值初始化。

并从§8。5/5:

值初始化T类型的对象是指:

  • 如果T是与用户声明的构造函数的类型,那么对于T默认构造函数被调用(如果T没有可访问的默认构造函数,则初始化不合格);
  • 如果T是一个没有用户声明构造函数的非联合类类型,那么每个非静态数据成员和基类组件T都进行了值初始化;
  • 如果T是一个数组类型,那么每个元素都是值初始化的;
  • 否则,该目的是零初始化

零初始化T类型的对象是指:

  • 如果T是标量类型,对象被设置为值的0(零)转换为T;
  • 如果T是非联合类类型,则每个非静态数据成员和每个基类子对象都被零初始化;
  • if T是一个联合类型,该对象的第一个命名数据成员)是零初始化的;
  • if T是一个数组类型,每个元素都是零初始化的;
  • 如果T是引用类型,则不执行初始化。

x(T()),y(T())可以与x(),y()代替,以代替直接值初始化xy。在大多数情况下,这将实现相同的净效应(假设T是可复制构建的),但在某些情况下,这将更有效,因此作为一般规则,此方法应始终优先。

3

一个实例(每个)T,由该类型的default constructor构建。

+0

我会添加“'x(),y()'大部分是等价的,复制将被优化。” – 2011-05-10 12:42:13

+0

是T是int类型,它们是如何初始化的? – thikonom 2011-05-10 12:42:57

+0

@DisplayName:'(int()== 0)== true' – 2011-05-10 12:43:57

1

在表达式中使用T()会创建一个类型为T的值右值和值 - 初始值为它。

如果T有默认构造该构造将被调用,如果T是一个聚合类型,属性中的每一个将值初始化,对于原始类型(在Java意义使用原始 :整数,浮点,双精度,炭,指针),它们将被设置为0。

2

有人来没有意识到,你可以通过缺省初始化是这样的:

VECTOR_2D() : x(), y() {}; 

所以,相反,他们正在通过做一些事情,这是一个有点像这样非常啰嗦

X x = X(); 

没有意义的副本应该被任何理智的编译器优化,但它仍然有点愚蠢。