澄清了C++中的初始化
clarification of initialization in C++
我在以下示例中真的很困惑:
#include <iostream>
class C {
public:
int a,b;
};
int main() {
C c{3,6};
std::cout<<c.a<<'n';
std::cout<<c.b<<'n';
return 0;
}
它工作正常并给出预期的结果。但是如果我像下面这样修改上面的代码。
#include <iostream>
class C {
int a,b;
public:
int get_a(){
return a;
}
int get_b(){
return b;
}
};
int main(){
C c{3,6};
std::cout<<c.get_a()<<'n';
std::cout<<c.get_b()<<'n';
return 0;
}
在上面的程序中编译器显示了多个错误。为什么第一个程序允许统一初始化,而第二个程序不允许统一初始化?我错在哪里?
默认情况下,c ++ class
成员是private
的,所以不指定你得到一个私有变量。因为您将类型设为私有,所以您不再免费获得聚合初始化,因此您需要为此类编写自己的构造函数:
class C{
C(int _a, int _b):
a(_a), b(_b)
{}
};
您只需要修复cout
的命名空间,您的代码应该可以正常编译:http://coliru.stacked-crooked.com/a/1d69f4f141d2bcd2
从标准:
[dcl.init.aggr] 聚合是一个数组或类,没有用户提供的构造函数,没有非静态数据成员的大括号或等于初始值设定项,没有私有或受保护的非静态数据成员,没有基类,也没有虚函数
在第一个代码中,您只有公共变量,因此代码有效,因为您有一个聚合,使变量私有是导致问题的原因,因为根据上述定义,它不再是聚合。
a
和b
在第二个示例中private
,因此无法从类外部访问。
您需要像第一个示例一样将行int a,b;
移动到public:
范围内。
你还需要std::
在cout
#include <iostream>
class C {
public:
int a,b; //Make public
int get_a(){
return a;
}
int get_b(){
return b;
}
};
int main(){
C c{3,6};
std::cout<<c.get_a()<<'n'; //use namespace std::
std::cout<<c.get_b()<<'n'; //use namespace std::
return 0;
}
在代码的修改版本中,您移动了public:
标签,以便a
和b
数据成员不再公开。因此,不能从类外部引用它们,即使不能由初始值设定项列表隐式引用。
第一个代码之所以有效,是因为数据成员a
和b
是公共的,因此可以从类外部访问它们。但是,在第二个代码中,它们被声明为私有的,因此无法从类外部访问它们。再次将它们声明为公共,或使用构造函数,如下所示(如果您仍希望它们为私有):
C(int x,int y) // This is a parameterised constructor
{
a=x;
b=y;
}
并将它们初始化为C c(3,6);
- 是否可以初始化不可复制类型的成员变量(或基类)
- C++使用整数的压缩数组初始化对象
- C++初始化基类
- 多成员Constexpr结构初始化
- 复制列表初始化的隐式转换的等级是多少
- 内联映射初始化的动态atexit析构函数崩溃
- 如何在C++中初始化嵌套类中的2个memeber
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 没有用于初始化C++中的变量模板的匹配构造函数
- 在未初始化映射的情况下,将值插入到映射的映射中
- C++成员初始化
- 为什么在C++中首先初始化成员类
- 同时具有"聚合初始化"和"模板推导"
- 初始化具有非默认构造函数的std::数组项的更好方法
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 在C和C++中初始化结构中的数组
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 在函数内部的声明中初始化数组,并在外部使用它
- 继承:构造函数,初始化C++11中基类的类C数组成员