C++ 声明与实例化

C++ 声明与实例化,c++,oop,C++,Oop,由于来自Java,我很难理解下面的代码。 在我的理解中,b只是在第3行声明,但没有实例化 在A类中创建B实例的教科书方法是什么 class A { private: B b; public: A() { //instantiate b here? } }; 编辑:如果B没有默认构造函数怎么办?例如,您可以在a的构造函数初始化列表中显式初始化B class A { B b; // private public: A : b() {} //

由于来自Java,我很难理解下面的代码。 在我的理解中,b只是在第3行声明,但没有实例化

在A类中创建B实例的教科书方法是什么

class A {
  private:
    B b;
  public:
    A() { 
      //instantiate b here?
    }
};

编辑:如果B没有默认构造函数怎么办?例如,您可以在
a
的构造函数初始化列表中显式初始化
B

class A {
  B b; // private
 public:
  A : b() {} // the compiler provides the equivalent of this if you don't
}; 
但是,
b
无论如何都会自动实例化。如果需要使用非默认构造函数构建
B
,或者如果
B
无法进行默认初始化,则上述操作是有意义的:

class A {
  B b; // private
 public:
  A : b(someParam) {}
};
可能无法在构造函数的初始化列表中正确初始化,在这种情况下,可以在构造函数的主体中完成赋值:

class A {
  B b; // private
 public:
  A {
    b = somethingComplicated...; // assigns new value to default constructed B.
  }
};

您已经在第3行中创建了
b
的实例。这行代码足够调用B的构造函数。如果你有这样的代码

class A {
  private:
    B *b;
  public:
    A() { 
      //instantiate b here?
    }
};
然后在
A的
构造函数中实例化
b
是有意义的

A()
 { 
    b = new B();
 }

正确的阶段是“C++初始化列表”。在调用构造函数之前调用/初始化此初始化列表

在默认构造函数的情况下,编译器等效构造函数将是
A():B(){}

非常好的参考书

在第3行,它只是一个B声明。但是在代码中的某个地方,您有:

A

这将调用A的构造函数。内部b私有成员已满或为垃圾,如未初始化。您是正确的,在可能的情况下,您可以并且可能应该在构造期间初始化成员变量。有两种方法可以做到这一点:

A () 
{
   b = B ();
}
就像你说的:


第二个版本(初始化列表)效率稍高一些,因为它直接在B中创建新的B对象。而第一个版本创建了一个临时文件,然后将其移动到b中。不管怎样,当您从传入的参数初始化成员时(对于非内置类型),都会出现这种情况。我假设在这种情况下也是这样,但有人可以澄清。

这是在构造函数体启动之前自动完成的(如果B有可访问的默认构造函数)。@jrok谢谢,所以对于使用默认构造函数生成的任何实例,上面的代码都可以?是的。有关编辑的答案,请参见juanchopanzas答案。关于“如果B没有默认构造函数怎么办?”+1。这称为“初始化列表”,因为它列出了成员的初始值。但这是一个糟糕的代码。不要介意原始指针不应该拥有内存,您应该使用初始化器列表,而不是构造函数主体中的赋值。
A () 
{
   b = B ();
}
A () : b (B())
{
}