澄清 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;
}
在上面的程序编译器中显示了多个错误。为什么在第一个程序中允许统一初始化但在第二个程序中不允许?我哪里错了?
a
和 b
在您的第二个示例中是 private
,因此无法从 class.
外部访问
您需要像第一个示例一样将行 int a,b;
移动到 public:
范围。
cout
前面还需要std::
#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
数据成员不再是 public。因此,它们不能从 class 外部引用,甚至不能被初始化列表隐式引用。
第一个代码起作用是因为数据成员 a
和 b
是 public,因此可以从 class 外部访问它们。但是,在第二个代码中,它们被声明为私有的,因此无法从 class 外部访问它们。要么再次将它们声明为 public,要么使用如下构造函数(如果您仍希望它们为私有):
C(int x,int y) // This is a parameterised constructor
{
a=x;
b=y;
}
并将它们初始化为C c(3,6);
默认情况下,c++ class
成员是 private
,因此无需指定即可获得私有变量。因为您将类型设为私有,所以您不再免费获得聚合初始化,因此您需要为此编写自己的构造函数 class:
class C{
C(int _a, int _b):
a(_a), b(_b)
{}
};
您只需修复 cout
的命名空间,您的代码应该可以正常编译:http://coliru.stacked-crooked.com/a/1d69f4f141d2bcd2
来自标准:
[dcl.init.aggr] An aggregate is an array or a class with no user-provided constructors, no brace-or-equal-initializers for non-static data members, no private or protected non-static data members, no base classes, and no virtual functions
在第一个代码中,您只有 public 个变量,所以代码可以工作,因为您有一个聚合,将变量设为私有是导致问题的原因,因为根据上述定义,它不再是聚合。
我真的对以下示例感到困惑:
#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;
}
在上面的程序编译器中显示了多个错误。为什么在第一个程序中允许统一初始化但在第二个程序中不允许?我哪里错了?
a
和 b
在您的第二个示例中是 private
,因此无法从 class.
您需要像第一个示例一样将行 int a,b;
移动到 public:
范围。
cout
前面还需要std::
#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
数据成员不再是 public。因此,它们不能从 class 外部引用,甚至不能被初始化列表隐式引用。
第一个代码起作用是因为数据成员 a
和 b
是 public,因此可以从 class 外部访问它们。但是,在第二个代码中,它们被声明为私有的,因此无法从 class 外部访问它们。要么再次将它们声明为 public,要么使用如下构造函数(如果您仍希望它们为私有):
C(int x,int y) // This is a parameterised constructor
{
a=x;
b=y;
}
并将它们初始化为C c(3,6);
默认情况下,c++ class
成员是 private
,因此无需指定即可获得私有变量。因为您将类型设为私有,所以您不再免费获得聚合初始化,因此您需要为此编写自己的构造函数 class:
class C{
C(int _a, int _b):
a(_a), b(_b)
{}
};
您只需修复 cout
的命名空间,您的代码应该可以正常编译:http://coliru.stacked-crooked.com/a/1d69f4f141d2bcd2
来自标准:
[dcl.init.aggr] An aggregate is an array or a class with no user-provided constructors, no brace-or-equal-initializers for non-static data members, no private or protected non-static data members, no base classes, and no virtual functions
在第一个代码中,您只有 public 个变量,所以代码可以工作,因为您有一个聚合,将变量设为私有是导致问题的原因,因为根据上述定义,它不再是聚合。