如何使用C ++中的列表初始化对象?

时间:2017-06-28 21:20:59

标签: c++ list

很抱歉,如果这是一个基本问题,但我找不到答案。我的问题是我在哪里可以找到一些关于如何使用列表初始化对象的文档。喜欢以下?

class TestClass {
public:
    int a;
    int b;
};

然后初始化一个对象:

TestClass obj = TestClass{ 1, 2};
    cout << obj.a << " " << obj.b << endl;

我只找到this页。

似乎是方法(2),但没有提到什么是规则。例如,a,b,...必须是公开的吗?我试过在它们之后添加一个私有的int c它不起作用。对于struct,我理解,我的问题是关于类。

由于

2 个答案:

答案 0 :(得分:0)

所以我发现你可以在C ++中用这种风格初始化任何东西,只要那个东西是一个聚合的&#39;。现在!什么是聚合?那么这取决于C ++标准 - C ++ 11,C ++ 14等...... - 我们在谈论什么。在C++11 aggregate initialization for classes with non-static member initializers的答案中雄辩地讨论了这一点。我真的希望这会有所帮助。

答案 1 :(得分:0)

首先,考虑基本建设。听起来您只想创建一个新的TestClass并在运行中指定其初始值。

您可以使用构造函数执行此操作:

/**
 * TestClass.hpp
 */
class TestClass
{
public:
    int a;
    int b;

    TestClass(int aInitial, int bInitial);
};

/**
 * TestClass.cpp
 */
TestClass::TestClass(int aInitial, int bInitial)
: a(aInitial),
  b(bInitial)
{

}

// ... which is the same as...
TestClass::TestClass(int aInitial, int bInitial)
{
    this->a = aInitial;
    this->b = bInitial;
}

/**
 * SomewhereElse.cpp
 */
...
TestClass foobar(1, 2);
std::cout << foobar.a << std::endl; // 1
std::cout << foobar.b << std::endl; // 2
...

但是,假设您已经考虑过这一点,而您实际上需要使用列表初始化。答案实际上是page you mentioned,让我们展开它。

当你想用自定义类写这样的东西时......

TestClass foobar = { 1, 2 };

首先需要一些手动工作。没有任何魔法可以自动将第0个索引分配给第一个成员,将第一个索引自动分配给第二个成员。

编译器需要一个接受std::initializer_list的赋值运算符或构造函数:

/**
 * TestClass.hpp
 */
class TestClass
{
public:
    int a;
    int b;

    TestClass(std::initializer_list<int> list); 
};

/**
 * TestClass.cpp
 */
TestClass::TestClass(std::initializer_list<int> list)
{
    if (list.size() != 2) {
        // Throw an error or set some defaults
    }

    int i = 0;
    for (int value : list) {
        if (i == 0) {
            this->a = value;
        } else {
            this->b = value;
        }

        i++;
    }
}

这将做你期望它做的事情。但那个构造函数非常时髦,不是吗?我们必须执行这个奇怪的for循环,因为std::initializer_list没有提供对其值的索引访问(换句话说,您不能list[0]或{{1 }})。

通过在构造函数中接受list[1](或其他类型的容器,如std::vectorstd::array等),您可以更轻松地阅读此内容。

这是有效的,因为那些容器中的std::list被接受为构造函数,并且可以执行隐式转换:

std::initializer_list