如何在C ++中调用父类的重写函数?

时间:2019-10-09 15:49:29

标签: c++ oop pointers

预期输出:

Child = 2
Parent = 1

我的代码:

class Parent{
    int a;
    public:
        void display(){
            a = 1;
            cout << "Parent = " << a << endl;
        }
};

class Child:public Parent{
    int b;
    public:
        void display(){
            b = 2;
            cout << "Child = " << b << endl;
        }
};

int main()
{
    Parent *p = new Child();
    Child c;

    //write your code here
    /* My solution :
      c.display();
      Parent* a = &c;
      a->display();
    */


}

我利用静态绑定成功调用了父类的display()成员函数

但是,我想知道这个问题是否有更好的解决方案。

使用此行Parent *p = new Child();的目的是什么?它是指向构造函数的指针吗?

该行与Parent *p = new Child;有什么区别?

2 个答案:

答案 0 :(得分:4)

这里有几点要说明:

  1. Child不会覆盖任何内容,它只是隐藏了基类方法。覆盖将需要virtual成员函数,并且您可以通过添加override关键字来验证方法是否实际上覆盖了基类函数。这两个类都不是多态的,因为任何地方都没有虚拟方法。

  2. 由于您的类不是多态的,因此您将永远只有静态绑定,没有动态绑定。 (您正确识别了这种情况)。

  3. 要调用在派生类中被重写或隐藏的基类函数,请在该调用之前添加基类名称和::,如下所示:

    class Child : public Parent{
      int b;
      public:
        void display(){
          Parent::display();
        }
    };
    
    // or
    
    int main()
    {
      Child c;
      c.Parent::display();
    }
    
  4. 在代码中Parent *p = new Child();Parent *p = new Child;之间没有区别,它们都调用默认构造函数来初始化新的子对象。对于类似int的类型,存在差异,new int;创建未初始化的int对象,new int();(或new int{};)将其初始化为零。

答案 1 :(得分:1)

  

如何在C ++中调用父类的重写函数?

在示例中,您实际上并未覆盖任何功能。只能覆盖虚拟成员函数,而display是非虚拟成员函数。

  

我利用静态绑定成功调用了父类的display()成员函数

您的解决方案之所以有效,是因为其中不涉及任何重写或虚拟功能。调用隐藏成员函数的另一种方法是使用范围解析运算符:

c.Parent::display();

即使函数是虚拟的,也将使用静态绑定。


  

使用此行Parent *p = new Child();的目的是什么?

它在您的程序中似乎没有任何用途。通常,new用于从免费存储区动态分配对象。

请注意,除非使用delete显式取消分配内存,否则内存将被泄漏。同样不是delete p会具有不确定的行为,因为它指向析构函数为非虚拟的基数。

  

它是指向构造函数的指针吗?

不。 p指向在免费商店中创建的动态对象。

  

该行与Parent *p = new Child;有什么区别?

不带括号,则使用默认的初始化语法。括号为空时,您可以使用值初始化。

对于简单可构造的类(例如Parent),默认初始化将默认初始化成员。对于整数成员,这将使成员保持未初始化状态。值初始化将改为对成员进行值初始化,对于整数,这意味着初始化为零。

对于非平凡可构造类(例如Child),默认值初始化和值初始化都会调用默认构造函数。