声明与实例化

Declaration vs. Instantiation

本文关键字:实例化 声明      更新时间:2023-10-16

从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's构造函数中实例化b是有意义的

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

您要查找的正确阶段是"C++初始化列表"。此初始化列表在构造函数被调用之前被调用/初始化

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

非常好的参考资料http://www.cprogramming.com/tutorial/initialization-lists-c++.html

在第3行,它只是B的声明。然而,在代码中的某个地方:

A a;

A a();

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

A () 
{
   b = B ();
}

就像你说的:

A () : b (B())
{
}

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