我应该使用哪一个以及为什么:{} vs = in c++
which one should i use and why: {} vs = in c++
我在看 MVA(Microsoft Visual Academy 的)教程时遇到了这两个运算符,即 {}
和 =
将值传递给变量。我做过 C 编程,所以我非常了解赋值运算符 =
。但是 {}
不是我目前使用的任何语言。
Kate 正在教 C++ 课程,所以她告诉 {}
用于复制。
但是我在下面的 class 中使用了运算符 {}
,当我尝试这样做时它显示了一些错误:
this->_width{new_width};
下面一个有效:
this->_width = new_width;
为什么会这样?我还使用 {}
在构造函数中传递值,但它们可以完美地工作。唯一的问题是成员函数。
class Rectangle
{
public:
void resize(int new_height, int new_width) { this->_width{new_width ; this->_height{new_height}; //member function
Rectangle(): _width{} , height{} {} //constructor
private:
int _width;
int _height;
};
非静态数据成员可以通过以下两种方式之一进行初始化:
1) 在构造函数的成员初始化器列表中。
struct S {
int n;
std::string s;
S() : n(7) // direct-initializes n, default-initializes s
{ }
};
2) 通过大括号或等号初始化器,它只是一个包含在成员声明中的初始化器,如果成员在成员初始化器列表中被省略时使用
struct S {
int n = 7;
std::string s{'a', 'b', 'c'};
S() // copy-initializes n, list-initializes s
{ }
};
您可以在成员声明中使用大括号初始值设定项。
此外,根据标准 N4296,§ 9.2,第 4 段:
A brace-or-equal-initializer shall appear only in the declaration of
a data member.
{}
可用于在 C++11 中初始化变量,其方式与在 C 中用于初始化数组和结构的方式相同。
这主要是为了提供语言语法的一致性(使用 {}
初始化将适用于所有上下文,而使用赋值运算符或 ()
初始化将适用于特定上下文。
列表初始化的另一个优点是它可以防止缩小 - 即它可以防止您在需要 double 时提供整数,或者在需要整数时提供 short必需的。通过这种方式,它可以帮助减少错误。
请注意,{}
不能用于将值传递给函数 - 只能用于构造新对象。
使用{}
在此上下文中称为统一初始化。引入它主要有两个原因。
首先,顾名思义,初始化是统一的,即它对于单个对象、数组、接受初始化列表的容器等看起来和工作都是一样的。
其次,同样重要的是,使用大括号不可能得到 most vexing parse,否则很可能是无意的:
A a(); // What does this do? What was probably intended?
B b{}; // And what does this do?
此外,作为奖励(@Richard Hodges 的荣誉),您可以避免使用统一初始化来缩小转换范围。
要从字面上回答问题 "which one should I use?",您最好使用 {}
,因为它只有优点,没有缺点(另外,Bjarne Stroustrup 建议使用它)。
我在看 MVA(Microsoft Visual Academy 的)教程时遇到了这两个运算符,即 {}
和 =
将值传递给变量。我做过 C 编程,所以我非常了解赋值运算符 =
。但是 {}
不是我目前使用的任何语言。
Kate 正在教 C++ 课程,所以她告诉 {}
用于复制。
但是我在下面的 class 中使用了运算符 {}
,当我尝试这样做时它显示了一些错误:
this->_width{new_width};
下面一个有效:
this->_width = new_width;
为什么会这样?我还使用 {}
在构造函数中传递值,但它们可以完美地工作。唯一的问题是成员函数。
class Rectangle
{
public:
void resize(int new_height, int new_width) { this->_width{new_width ; this->_height{new_height}; //member function
Rectangle(): _width{} , height{} {} //constructor
private:
int _width;
int _height;
};
非静态数据成员可以通过以下两种方式之一进行初始化:
1) 在构造函数的成员初始化器列表中。
struct S {
int n;
std::string s;
S() : n(7) // direct-initializes n, default-initializes s
{ }
};
2) 通过大括号或等号初始化器,它只是一个包含在成员声明中的初始化器,如果成员在成员初始化器列表中被省略时使用
struct S {
int n = 7;
std::string s{'a', 'b', 'c'};
S() // copy-initializes n, list-initializes s
{ }
};
您可以在成员声明中使用大括号初始值设定项。
此外,根据标准 N4296,§ 9.2,第 4 段:
A brace-or-equal-initializer shall appear only in the declaration of a data member.
{}
可用于在 C++11 中初始化变量,其方式与在 C 中用于初始化数组和结构的方式相同。
这主要是为了提供语言语法的一致性(使用 {}
初始化将适用于所有上下文,而使用赋值运算符或 ()
初始化将适用于特定上下文。
列表初始化的另一个优点是它可以防止缩小 - 即它可以防止您在需要 double 时提供整数,或者在需要整数时提供 short必需的。通过这种方式,它可以帮助减少错误。
请注意,{}
不能用于将值传递给函数 - 只能用于构造新对象。
使用{}
在此上下文中称为统一初始化。引入它主要有两个原因。
首先,顾名思义,初始化是统一的,即它对于单个对象、数组、接受初始化列表的容器等看起来和工作都是一样的。
其次,同样重要的是,使用大括号不可能得到 most vexing parse,否则很可能是无意的:
A a(); // What does this do? What was probably intended?
B b{}; // And what does this do?
此外,作为奖励(@Richard Hodges 的荣誉),您可以避免使用统一初始化来缩小转换范围。
要从字面上回答问题 "which one should I use?",您最好使用 {}
,因为它只有优点,没有缺点(另外,Bjarne Stroustrup 建议使用它)。