【问题标题】:How to initialize a class member data with other member data of this class ?如何用这个类的其他成员数据初始化一个类成员数据?
【发布时间】:2011-10-29 17:02:05
【问题描述】:

我有A班和B班。 B 是 A 的成员。 我需要用 A 的其他数据成员初始化 B。

class A;
class B
{
 public:
    B(A& a){cout << "B constr is run \n";}
};

class A
{
 public:
    A(){}

    void initB(A& a){b(a); cout << "A call init B \n"; }
 private:
    // other members ...

    B b;
};

int main()
{
    A a;
    a.initB(a);

}

我得到编译错误:

classIns.cpp: In constructor âA::A()â:
classIns.cpp:14: error: no matching function for call to âB::B()â
classIns.cpp:8: note: candidates are: B::B(A&)
classIns.cpp:6: note:                 B::B(const B&)
classIns.cpp: In member function âvoid A::initB(A&)â:
classIns.cpp:16: error: no match for call to â(B) (A&)â

为什么 A(){} 需要调用 B::B() ?

如何用 A 的其他数据成员初始化 B ?

谢谢

【问题讨论】:

  • 为什么有五个答案而没有“初始化列表”的实例

标签: c++ class object constructor


【解决方案1】:

B 没有默认构造函数,这意味着您必须A 的ctor 中初始化它。

struct A {
    A() : b(*this) {}
private:
    B b;
};

任何时候你想使用init-like 成员,你可能做错了。构造函数完成后,对象应该始终有效。

【讨论】:

  • @user1000107:这称为初始化列表,是初始化所有成员的推荐方式。
【解决方案2】:

你可以在A构造函数中使用初始化链:

class B
{
    public:
        B(Type1 x, Type2 y)
        {

        }
        void init(Type1 x, Type2 y) { ........} 
};
class A
{
    public:
        A() : Amember1(), Amember2(), b(Amember1, Amember2) {}
    private:
        Type1 Amember1;
        .....
        B b;
};

但是你不能在 initB 方法中调用 B 构造函数,因为 b 已经被构造了。 您可以对 A 数据使用 B::init() 方法,例如:

void A::initB(A& a){ b.init(a.Amember1, a.Amember2); cout << "A call init B \n"; }

【讨论】:

    【解决方案3】:

    像这样:

    void initB(A& a){
      b = B(a); 
      cout << "A call init B \n"; 
    }
    

    当然,B 类需要一个默认构造函数,以及一个引用 A 类型对象的复制构造函数。

    【讨论】:

    • 构造函数返回nothing以便分配给别的东西。
    • @Mahesh 不,它没有。但是,B 类应该将赋值运算符声明为B&amp; operator=( const A&amp; )
    • 在这种情况下,只需b = a; 就足够了。创建的临时对象的类型为B,并且与您当前拥有的赋值运算符参数(即 const A& )不兼容。因此,我相信即使提供了= 运算符,除非您执行b=a;,否则sn-p 也不会编译
    • @Mahesh 好吧。修复了我的回答中的小错误(它应该是复制构造函数,而不是构造函数,它引用了 A 类型的对象)。谢谢
    【解决方案4】:

    为什么 A(){} 需要调用 B::B() ?

    因为 A 有一个数据成员 B 需要在创建 A 类的实例时进行初始化。在您的情况下, b 使用默认的 B c'tor 进行初始化。

    因为你要为 B 指定一个构造函数

    public:
        B(A& a){cout << "B constr is run \n";}
    

    默认构造函数:

        B(){}
    

    不是由编译器自动生成的。所以它会抱怨。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多