声明与实例化
Declaration vs. Instantiation
从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中。无论如何,当您从传入的参数初始化成员时(对于非内建类型)都会出现这种情况。我假设在这种情况下也是如此,但有人会澄清的。
相关文章:
- 单行类声明和实例化
- 从模板基类派生是否在派生类声明的点实例化模板
- 在实例化封闭类模板之后,我们可以声明模板类成员的部分专用化吗
- 我们可以在没有新实例化的情况下声明一个抽象方法来返回抽象超类中的子类对象吗
- 在不使用默认构造函数的情况下声明 POD 结构时,会实例化什么?
- C++17 单独的显式方法模板实例化声明和定义
- 声明基类类型的指针,但随后通过指向子类来实例化它.这是良好的编程实践吗?
- 模板函数是否以内联方式声明 constexpr,即使实例化不是 constexpr
- C 在对象实例化时如何分开声明和构造函数
- 无法在好友函数中实例化类?我没有得到在范围错误中声明
- 仅标头模板(外部模板)的显式实例化声明
- 声明无法解决"实例化后的显式专用化"错误
- gcc 中的模板显式实例化(定义和声明)
- 类模板实例化错误:未在此范围内声明类型
- 未在此作用域中声明实例化类/的作用域
- 使用显式实例化声明删除反向指针会导致 std::bad_weak_ptr 异常
- 为什么为模板实例化声明运行时多态性会导致链接器错误
- c++ 11:显式实例化声明vs显式实例化定义
- 友元声明和显式模板实例化声明
- 仅针对类的特定模板实例化声明成员函数