类C、构造函数和统一初始化之间有什么区别? 据我所知,C++中有三种初始化变量的方法。 int x = 0; // C-like initialization int x (0); // Constructor initialization int x {0}; // Uniform initialization

类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。在实践中,移动或复制将被省略,因此结果与第二种样式相同;唯一的区别是,如果没有可访问的复制或移动构造函数,第一个将失败

统一初始化是为提供更统一的语法来初始化不同类型的变量而引入的,这需要不同的语法

类C、构造函数和统一初始化之间有什么区别?我应该始终使用统一初始化吗

类c、构造函数和统一初始化之间有什么区别

对于像
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的元素 你也不应该称之为“统一初始化”,因为它在任何意义上都不是“统一的”。官方术语是“括号初始化”

类c、构造函数和统一初始化之间有什么区别

对于像
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
    arr+4
  • 创建向量并将元素单独或在循环中推回()
  • 使用C++11,您可以使用

    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
    对象


    规则是针对对象,除非你有理由不使用大括号初始化。

    首先,我建议看看Herb Sutter的文章,他在文章中给出了一些关于该主题的建议。大括号初始化讨论从开始

    当您谈论基本数据类型时,这三种类型都会产生相同的结果。我个人更喜欢使用旧的
    intx=0
    语法,但这取决于个人偏好

    对于类类型,大括号初始化和旧sc