C++ Как перегрузить метод так, чтобы при вызове из списка (родительского) вызывался дочерний метод

Рейтинг: 0Ответов: 2Опубликовано: 04.05.2023

Я бы хотел чтобы дочерние структуры были в списке с общим типом чтобы позже вызывать для них метод с похожим именем(и аргументами) но разными реализациями

Через virtual и override не получильсь:

#include <iostream>

using namespace std;

struct Parent {
    virtual void say() {
        cout << "parent say\n";
    }
};

struct Child : Parent {
    void say() override {
        cout << "child say\n";
    }
};

int main() {
    Parent a[2];

    Child x;
    a[1] = x;

    a[0].say();
    a[1].say();
    return 0;
}

На выходе:

parent say
parent say

То есть тут я хочу изменить метод say только у a[1]. Или так нельзя? Ведь имя и аргументы те же

Ответы

▲ 1Принят

Это назывется полиморфное наследование, которое реализуется через upcasting производного класса к базовому. Но такие методы должны быть виртуальными, т.е. должна быть создана виртуальная таблица методов (vtable). Upcasting происходит неявно для ссылок и указателей:

Parent parent;
Child child;
Parent* array[2] = {&parent,&child};
for (auto element : array) element->say();

Parent& ref{child};
ref.say();
▲ 1

При копировании Child объекта новому объекту типа Parent не меняется тип нового объекта, он как был Parent так и остался. Происходит копирование только базовой части аргумента.
Виртуальные вызовы будут работать только если порождённый объект спрятан под указателем или ссылкой базового типа.

  Parent p = x ; // p - это новый объект Parent
  p.say();  

  Parent & l = x ; // l - это ссылка на реальный Child
  l.say();