c++ 在class A的构造函数中初始化另一个类的对象(调用B::B())时报错: error: no matching function for call to 'B:B()'
c++ 在class A的构造函数中初始化另一个类的对象(调用B::B())时报错: error: no matching function for call to 'B:B()'
1. 现象
看如下代码:
class B, 构造函数接受一个int参数i_b, 并赋值给this->b,
#include <iostream>
class B{
public:
int b;
B(int i_b){
this->b = i_b;
}
};
class A, 构造函数A::A()会调用B的构造函数B::B(), 这时:
- 声明o_b时, 不能带括号和参数, 否则会报错: error: class 'A' does not have any field named 'o_b'
- A()中初始化o_b时, 要使用列表初始化, 不能使用赋值初始化, 否则会报错: error: no matching function for call to 'B:B()'
class A
{
public:
int a ;
//变量声明, 由于o_b要在A的构造函数A()中初始化, 所以此处不能带括号和参数
// 如果带了括号, 写成B o_b(),
// 或者带了参数, 写成B o_b(int i_b)或B o_b(int)
// 会报错: error: class 'A' does not have any field named 'o_b',
//如果o_b不在A的构造函数A()中初始化, 此处可以带括号和参数: B o_b = B(30)
B o_b;
//构造函数, 使用列表初始化(主要针对o_b, this->a可以使用赋值初始化)
A(int i_a):a(i_a), o_b(B(i_a*2))
{
};
//如果写成如下代码, 使用赋值初始化, 会报错: error: no matching function for call to 'B:B()'
//A(int i_a)
//{
// this->a = i_a;
// this->o_b = B(i_a * 2);
//}
void show(){
std::cout << "a=" << this->a << ", b=" << this->o_b.b << std::endl;
}
};
main 函数, 把10传给o_a, 会打印: a=10, b=20
int main(){
A o_a(10);
o_a.show(); //打印a=10, b=20
}
2. 说明
2.1 class成员的初始化方式
有两种初始化方式:
- 赋值初始化: 在构造函数体没通过赋值进行初始化.
A::A(int i_a)
{
this->a = i_a;
this->o_b = B(i_a*2); //此语句会报错, 构造函数中对其他对象初始化, 只能使用列表初始化.
}
- 列表初始化: 在冒号后面使用初始化列表进行初始化.
A::A(int i_a): a(i_a), o_b(B(i_a*2))
{
}
2.2 以下几种情况必须使用列表初始化
- 初始化一个引用成员时;
- 初始化一个const成员时;
- 调用基类的构造函数, 同时这个构造函数拥有参数时;
- 调用其他类的构造函数, 同时这个构造函数拥有参数时;