3

这是我正在尝试做的简化版本

class Firstclass
    {
    public:
    Firstclass(int x)
        {
        //do things with x;
        }
    };

class Secondclass
    {
    public:
    Secondclass()
        {
        Firstclass a(10);
        }

    void func()
        {
        //Do things with a
        }

    private:
    Firstclass a;
    };

所以我有一个类(Firstclass),它的构造函数接受一个 int 参数。现在我想在另一个类(Secondclass)的构造函数中创建该类的一个实例。

线条

private:
Firstclass a;

如果 a 只是一个变量而不是一个类,我会做什么:首先提及它,以便我可以在其他地方使用它(例如在函数 func() 中)。这似乎不适用于类,因为编译器不理解 Secondclass 的构造函数应该做什么。

我该如何正确地做到这一点?

4

3 回答 3

8

通过成员初始化器列表对其进行初始化:

Secondclass() : a(10) { }

这是必需的,因为Firstclass没有默认构造函数。此外,带参数的类内初始化与函数声明有歧义,因此您可以在类主体中进行。在 C++11 中,这通过聚合初始化来解决:

Firstclass a{10};
于 2013-08-10T17:09:03.427 回答
3

正确执行此操作的一种方法是使用构造函数初始化列表:

Secondclass) : a(10)
{
    // ...
}

初始化列表还允许您指定为作为类字段的对象调用哪个构造函数。

因此,不要尝试使用不存在的默认构造函数来初始化Secondclass's 成员,而是通过使用构造函数初始化列表来指定要调用的构造函数。a


自 C++11 以来,有一种新的方法可以做到这一点。它被称为聚合初始化。语法是:

T object {arg1, arg2, ...};

因为在这种情况下a是类的非静态成员,所以它将被复制初始化

以下是复制初始化在这种特殊情况下的作用:

检查构造函数,Firstclass并通过重载决议选择最佳匹配。然后调用构造函数来初始化对象。

所以如果你想使用 C++11,你的类应该是这样的:

class Secondclass
{
public:
    Secondclass()
    {
    }

    void func()
    {
        //Do things with a
    }

private:
    Firstclass a{10};
};

只是指出另一个错误:

Secondclass()
{
    Firstclass a(10);
}

你在这里没有做你想的那样。在这里,您声明了一个仅存在于构造函数范围内a的类型变量Firstclass,它将在范围结束时被破坏。它与a成员不同。

于 2013-08-10T17:09:34.937 回答
2

FirstClass没有默认构造函数,所以需要使用Secondclass' 构造函数初始化列表:

Secondclass() : a(10) {}

C++11 允许您在声明时初始化非静态数据成员,因此您也可以这样做:

class Firstclass
{
  ....
private:
 Firstclass a{10};
};

你在这里做什么:

Secondclass()
{
  Firstclass a(10);
}

在两个方面是错误的:1)如上所述,FirstClass没有默认构造函数,并且通过不在初始化a列表中进行初始化,您正在调用其默认构造函数。2)您正在声明一个局部变量atype Firstclass,它只存在于构造函数主体的范围内。这您的数据成员不同a

于 2013-08-10T17:08:06.037 回答