澄清C ++中的初始化

时间:2015-05-01 14:55:53

标签: c++ initialization uniform-initialization

我对以下示例感到困惑:

#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;
}

在上面的程序中,编译器显示多个错误。为什么在第一个程序中允许统一初始化而在第二个程哪里错了?

3 个答案:

答案 0 :(得分:3)

默认情况下,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] 聚合是一个数组或类,没有用户提供的构造函数,没有用于非静态数据成员的大括号或等号初始值,没有私有或者受保护的非静态数据成员,没有基类,也没有虚函数

在第一个代码中,您只有公共变量,因此代码有效,因为您有一个聚合,使变量私有是导致问题的原因,因为它不再是根据上述定义的聚合。

答案 1 :(得分:1)

在您的第二个示例中,

abprivate,因此无法从课堂外访问。

答案 2 :(得分:1)

第一个代码有效,因为数据成员ab是公开的,因此可以从课外访问它们。但是,在第二个代码中,它们被声明为私有,因此无法从类外部访问它们。要么将它们再次声明为public,要么使用如下构造函数(如果您仍然希望它们是私有的):

 C(int x,int y)   // This is a parameterised constructor
    {
        a=x;
        b=y;
    }

并将其初始化为C c(3,6);