类C、构造函数和统一初始化之间有什么区别? 据我所知,C++中有三种初始化变量的方法。 int x = 0; // C-like initialization int x (0); // Constructor initialization int x {0}; // Uniform initialization
统一初始化是为提供更统一的语法来初始化不同类型的变量而引入的,这需要不同的语法 类C、构造函数和统一初始化之间有什么区别?我应该始终使用统一初始化吗 类c、构造函数和统一初始化之间有什么区别 对于像类C、构造函数和统一初始化之间有什么区别? 据我所知,C++中有三种初始化变量的方法。 int x = 0; // C-like initialization int x (0); // Constructor initialization int x {0}; // Uniform initialization,c++,c++11,initialization,c++03,variable-initialization,C++,C++11,Initialization,C++03,Variable Initialization,统一初始化是为提供更统一的语法来初始化不同类型的变量而引入的,这需要不同的语法 类C、构造函数和统一初始化之间有什么区别?我应该始终使用统一初始化吗 类c、构造函数和统一初始化之间有什么区别 对于像int这样的基本类型,没有实际的区别;让我们来考虑一个类类型 t>代码>。 第一种风格相当于 T x(T(0)); 从初始化器表达式创建临时对象,然后通过移动或复制该对象来初始化x。在实践中,移动或复制将被省略,因此结果与第二种样式相同;唯一的区别是,如果没有可访问的复制或移动构造函数,第一个将失败
int
这样的基本类型,没有实际的区别;让我们来考虑一个类类型<代码> t>代码>。
第一种风格相当于
T x(T(0));
从初始化器表达式创建临时对象,然后通过移动或复制该对象来初始化x
。在实践中,移动或复制将被省略,因此结果与第二种样式相同;唯一的区别是,如果没有可访问的复制或移动构造函数,第一个将失败
第二种方法使用一个接受一个参数的构造函数直接初始化对象,如果没有合适的构造函数,则会给出一个错误
第三个取决于可用的构造函数
- 如果有一个构造函数使用
,它会使用它李>std::initializer\u list
- 否则,如果有一个构造函数接受一个合适类型的参数,它就会使用它李>
- 否则,如果它是一个包含一个成员的聚合(没有构造函数),则该成员的初始值为零李>
- 否则,这是一个错误
初始值设定项列表
构造函数和采用其他参数类型的构造函数。例如:
std::vector<int> v1(10, 42); // 10 elements with value 42
std::vector<int> v2{10, 42}; // 2 elements with values 10 and 42
vector<int> v (100); // Creates a 100-element vector
vector<int> v {100}; // Creates a 1-element vector, holding the value 100.
标准向量v1(10,42);//值为42的10个元素
std::向量v2{10,42};//2个值为10和42的元素
你也不应该称之为“统一初始化”,因为它在任何意义上都不是“统一的”。官方术语是“括号初始化”。首先,我建议大家看看赫伯·萨特(Herb Sutter)的文章,他在文章中给出了一些关于这个主题的建议。大括号初始化讨论从开始 当您谈论基本数据类型时,这三种类型都会产生相同的结果。我个人更喜欢使用旧的
intx=0
语法,但这取决于个人偏好
对于类类型,大括号初始化和老式构造函数初始化不能完全互换。例如:
std::vector<int> v1(10, 42); // 10 elements with value 42
std::vector<int> v2{10, 42}; // 2 elements with values 10 and 42
vector<int> v (100); // Creates a 100-element vector
vector<int> v {100}; // Creates a 1-element vector, holding the value 100.
创建一个std::initializer\u列表
,其标识符为var
关于初始值设定项列表的一点是,它们提供了一致性,这是一个受欢迎的变化,与之前的可用性不同。例如,如果要在C++中初始化数组,则使用:
int arr[] = {1, 2, 3, 4};
但是,如果要使用相同的元素初始化向量
,则必须:
arr
和arr+4
vector<int> v = {1, 2, 3, 4}; // Same syntax. Nice! Note that the = is optional
不允许使用origin
和extents
临时变量创建矩形
对象,因为该语句被解析为函数声明。茨克茨克。因此,通常情况下,您必须:
origin o;
extents e;
rectangle w(o, e);
通过大括号初始化,您可以动态创建它们,并且
rectangle w {origin(), extents()};
将按预期工作,即传递给构造函数,构造函数重载的第一个参数是origin
对象,第二个参数是extensts
对象
规则适用于对象,除非你有理由不使用大括号初始化。你所说的差异是什么意思?对于int这样的基本数据类型,它们是完全相同的。我会用“C类”来做int,这是最直观的方式。我对C++是新的,但是我在思考引擎盖后面发生的事情。我正在阅读,但我假设构造函数初始化调用对象中的构造函数方法。在这个构造函数中发生了什么?我还听说统一初始化方法在某些情况下会回退到构造函数初始化。我仍然不明白。当我读到某个地方时,C++会把它解释成函数声明,如果它看起来像一个函数声明。两个
矩形w(原点(),范围())代码>和矩形w(o,e)
看起来像函数声明,它们之间有什么区别?@Cupidvogel第二个示例不是函数声明,因为这里没有参数的类型o
和e
分别是origin
和extends
的实例。是的,但第一个也是类似的,对吗o
实际上是origin()。矩形w(origin(),extents())
中的origin()
被解析为指向不带参数并返回origin
对象的函数的指针。与区段()相同。所以它们是类型。“[…]关于基本数据类型,所有3个都会产生相同的结果。”-这不是100%正确,因为大括号初始化不允许缩小转换,而其他类型允许缩小转换(char c(999);
有效,而char c{999};
不适用于8位char
)。您也没有提到tx=…
执行拷贝初始化(我同意,大多数编译器都会省略这一点)如果构造函数T(int)
被标记为显式(这对于某些标准容器来说是很常见的!),则code>也将失败。您在该语句中是否出错?“如果它是一个包含一个成员的聚合(没有构造函数),则该成员的初始值为零;”?我不明白it@PatrickParker我想他会喜欢我的