Как вызвать переопределенную функцию родительского класса в C ++? - PullRequest
0 голосов
/ 09 октября 2019

Ожидаемый вывод:

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 ]

4 голосов
/ 09 октября 2019

Здесь нужно сделать несколько замечаний:

  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 голос
/ 09 октября 2019

Как вызвать переопределенную функцию родительского класса в C ++?

На самом деле вы не переопределили ни одну функцию в своем примере. Только виртуальные функции-члены могут быть переопределены, и display не является виртуальным.

Я использовал статическое связывание для успешного вызова функции-члена display () родительского класса

Ваше решение работает, потому что в нем нет переопределенных или виртуальных функций. Другой способ вызова скрытой функции-члена - использовать оператор разрешения области:

c.Parent::display();

При этом будет использоваться статическое связывание, даже если функция была виртуальной.


Чтоэто цель иметь эту строку Parent *p = new Child();?

Кажется, она не имеет никакой цели в вашей программе. В общем, new используется для динамического выделения объектов из свободного хранилища.

Обратите внимание, что память будет утечка, если вы явно не освободите ее с помощью delete. Также не то, что delete p будет иметь неопределенное поведение, потому что оно указывает на базу, деструктор которой не виртуален.

Указатель, указывающий на конструктор?

Нет. p указывает на динамический объект, который был создан в бесплатном хранилище.

В чем разница между этой строкой и Parent *p = new Child;?

Без скобок используется синтаксис инициализации по умолчанию. С пустыми скобками вы используете значение инициализации.

В случае тривиально возводимых классов (таких как Parent), инициализация по умолчанию будет инициализировать элементы по умолчанию. В случае целочисленных членов, это оставляет членов неинициализированными. Вместо этого инициализация значения будет инициализировать значения членов, что для целых чисел означает инициализацию на ноль.

В случае нетривиально конструируемых классов (таких как Child) инициализация по умолчанию и инициализация значения вызывают конструктор по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...