【问题标题】:How to Institiate an object in when we have pure virtual function hirerachy?当我们有纯虚函数层次结构时,如何实例化一个对象?
【发布时间】:2019-08-23 06:18:05
【问题描述】:
class A{
    public: virtual void getName() = 0;
};

class B: public A{
    public:
        B(int a){
            cout<< "B Name : " << a <<endl;
        }
        void getName() override { cout << "Class B" << endl; }
};

class C: public B{
    public:
      C(int a){
            cout<< "C Name : " << a <<endl;
        }
        void getName() override { cout << "Class C" << endl; }
};

int main()
{
    B *b = new B(10);
    b->getName();

    C *c = new C(20);
    c->getName();
}

我正在尝试创建 BC 类的对象。但它给了我这个错误

main.cpp:31:15: error: no matching function for call to ‘B::B()’
       C(int a){
               ^
main.cpp:22:9: note: candidate: B::B(int)
         B(int a){
         ^ 

谁能向我解释为什么会这样?为什么它不创建类对象?

【问题讨论】:

  • 也不相关:请让那些单参数构造函数explicit

标签: c++ function initialization virtual


【解决方案1】:

此问题与virtual 函数无关。

您必须明确指定B 的哪个构造函数应该用于初始化member initializer list 中的基础子对象B,否则将使用B 的默认构造函数但B 没有一。 (注意B 有一个用户定义的构造函数采用int 然后不会为B 生成默认构造函数。)

对于不能默认初始化的成员,例如引用成员和 const 限定类型的成员,必须指定成员初始化器。

例如

C(int a) : B(a) {
//       ^^^^^^
    cout<< "C Name : " << a <<endl;
}

【讨论】:

    【解决方案2】:
    B(int a){
            cout<< "B Name : " << a <<endl;
        }
    

    在构造C时,B也需要构造。如果不指定如何初始化子类(通过初始化列表指定要调用的构造函数),base 是默认构造的,需要默认构造函数。

    由于您为B 类定义了构造函数,因此没有为B 生成默认构造函数。您可以为B 定义一个默认构造函数,也可以通过初始化列表指定B(int a)

    请注意,您可以创建B 的对象,而无需为基类A 指定构造函数,因为A 类具有生成的默认构造函数。

    【讨论】:

      【解决方案3】:

      问题与任何父类的抽象性无关,这是因为您的C 构造函数试图通过B 初始化父B默认构造函数 ,它没有。

      你需要通过构造函数初始化列表“调用”参数化的B构造函数

      C(int a)
          : B(a)  // "Calls" the B constructor
      {
      }
      

      可以选择将默认构造函数添加到B 类。

      【讨论】:

        猜你喜欢
        • 2021-08-06
        • 2023-04-04
        • 2012-10-13
        • 2012-04-04
        • 2012-02-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-02
        相关资源
        最近更新 更多