类C,构造函数和统一初始化之间有什么区别?
TTBOMK,在C ++中有三种方法来初始化一个variables。
int x = 0; // C-like initialization int x (0); // Constructor initialization int x {0}; // Uniform initialization
C ++ 11为统一初始化提供了一个更统一的语法来初始化不同types的variables,这些variables在C ++ 03中需要不同的语法。
类C,构造函数和统一初始化之间有什么区别? 我应该总是使用统一的初始化?
首先,我build议看一下Herb Sutter的以下谈话 ,他在这个话题中提出了一些build议。 大括号初始化讨论从23:00左右开始。
当你在谈论原始数据types时,所有3都会得到相同的结果。 我个人更喜欢坚持旧的int x = 0
语法,但归结为个人偏好。
对于类types,括号初始化和老派构造函数初始化不是完全可以互换的。 例如:
vector<int> v (100); // Creates a 100-element vector vector<int> v {100}; // Creates a 1-element vector, holding the value 100.
这是因为std::vector
有一个构造函数,它明确定义了std::initializer_list
作为唯一的参数。 请记住这一点
auto var = {1, 2};
创build一个std::initializer_list
, var
作为其标识符。
关于初始化列表的事情是,它们提供的一致性是事先可用的一个可喜的变化。 例如,如果你要用C ++初始化一个数组,你可以使用:
int arr[] = {1, 2, 3, 4};
但是,如果你想用同样的元素初始化一个vector<int>
,你必须:
- 初始化上面的arr,然后通过
arr
和arr + 4
- 分别创buildvector和push_back()元素或循环。
用C ++ 11,你可以使用
vector<int> v = {1, 2, 3, 4}; // Same syntax. Nice! Note that the = is optional
大括号初始化有用的另一个实例是它提供了一个解决方法,以C ++的最令人头痛的parsing 。 从谈话中,假设我们有两个类, origin
和extents
,其实例可以被传递来构造rectangle
types的另一个对象。 以下声明:
rectangle w(origin(), extents());
不允许使用origin
和extents
临时对象创buildrectangle
对象,因为该语句被parsing为函数声明。 Tsk tsk。 所以通常情况下,你必须这样做:
origin o; extents e; rectangle w(o, e);
使用大括号初始化,您可以即时创build它们
rectangle w {origin(), extents()};
将按预期工作,即传递给构造函数,该构造函数的第一个参数是一个origin
对象,第二个是extents
对象。
规则是针对对象,除非你有理由不使用大括号初始化。
c类,构造函数和统一初始化之间有什么区别?
对于像int
这样的原始types,没有实际的区别。 所以我们来考虑一个类typesT
第一种风格相当于
T x(T(0));
从初始化expression式创build临时对象,然后通过移动或复制x
来初始化x
。 在实践中,移动或复制将被消除,从而结果与第二种方式相同; 唯一的区别是,如果没有可访问的副本或移动构造函数,则第一个将失败。
第二个直接使用一个构造函数初始化对象,该构造函数接受一个参数,如果没有合适的构造函数,则返回错误。
第三个取决于什么构造函数可用。
- 如果有构造函数采取
std::initializer_list
,它使用它; - 否则,如果有一个构造函数接受一个合适types的单个参数,则使用该参数;
- 否则,如果它是一个成员的聚集(没有构造函数),则该成员初始化为零;
- 否则,这是一个错误。
我应该总是使用统一的初始化?
不,有时你需要函数式初始化来区分initializer_list
构造函数和其他参数types。 例如:
std::vector<int> v1(10, 42); // 10 elements with value 42 std::vector<int> v2{10, 42}; // 2 elements with values 10 and 42
你也不应该称之为“统一初始化”,因为它在任何有意义的意义上都不是“统一的”。 官方名称是“大括号初始化”。