C ++如何初始化成员对象?

时间:2015-02-10 16:33:47

标签: c++

有没有办法在下面的例子的第一部分初始化(?)C类成员变量c?或者我必须使用示例第二部分中显示的new()方法吗?

B类将A类作为注入依赖项。 C类也是如此.B类还由C类组成。

如何将注入的A注入B的成员C?

第1部分

class A { // ...; };

class C {
public:
    C(A &a) : a(a) {}   // constructor
};


// Does not work as is.  Want to make compiler manage C lifetime.
class B {
public:
    B(A &a);    // constructor

    C c(a);     // member variable
};

// constructor
B::B(A &a) : a(a) {
}

第2部分

// Works, but requires programmer to manage C's lifetime.
class B {
public:
    B(A &a);    // constructor

    C *c;       // member variable
};

// constructor
B::B(A &a) : a(a) {
    c = new C(a);
}

以下几个好的答案!我为这个令人困惑的例子道歉。我已经投了所有好的答案和问题。不幸的是,我只能将一个答案标记为已接受的答案,所以我选择了第一个给我“啊哈”的时刻,在这个时刻我看到了解决我真正问题的方法,这比我这里的蹩脚例子更复杂。

4 个答案:

答案 0 :(得分:2)

成员变量在构造函数的初始化列表中(在正文之前)初始化,因此您需要这样做:

B::B(A &a)
    : c(a) // Calls constructor C(a) on member c
{}

答案 1 :(得分:2)

你几乎拥有它:

class B {
public:
    B(A &a);

    C c(a); //see note 1
};

B::B(A &a) : a(a) { //see note 2
}

注1:

此处C c(a);存在两个问题:

  1. a不在范围内。 a仅存在于构造函数的范围内,因此需要从那里初始化c
  2. 在C ++ 11之前,禁止使用非静态数据成员初始值设定项(NSDMI)。但是,即使在C ++ 11中,在初始化NSDMI时也必须使用等号(C c = value;)或大括号(C c{value};)。
  3. 注2:

    你几乎做对了:

    B::B(A &a) : a(a)
    

    您尝试使用给定构造函数的参数初始化名为a的数据成员。您实际上想要像这样初始化c,而不是不存在的a

    B::B(A &a) : c(a)
    

    c的生命周期将是B类实例的生命周期。当然不需要使用动态内存管理。

答案 2 :(得分:1)

  

"如何将注入的A注册到B&C的成员C?"

您可以使用B的构造函数成员初始值列表

来执行此操作
class B {
public:
    B(A &a) : c(a) {
           // ^^^^
    }

    C c; // <<< It's not possible to initialize members in their
         //     declaration.
};

答案 3 :(得分:1)

以下内容:

C(A &a) : a(a) {}

将无法编译,因为a(初始化列表中的第一个a)不是C的成员变量。

同样适用于B的构造函数。