C ++ вызывает функцию родительского класса, которая использует замещающую функцию - PullRequest
0 голосов
/ 19 июня 2020

Итак, мне было интересно, возможно ли в C ++ вызвать метод родительского класса, который использует замещенный метод, без использования родительской версии замещенного метода. (Я знаю, что это непонятно, поэтому я привел пример!)

Например, ниже я хотел бы вызвать версию findPath () класса A из объекта класса B, используя метод addPoint, который определен по классу B. В настоящее время, если я вызываю findPath () из объекта класса B, он использует метод addPoint, определенный в классе A.

Фактический результат:

A.findPath (), путь = {1,2,3,4,5,6,7,8,9,10)

B.findPath (), path = {1,2,3,4,5,6, 7,8,9,10)

Желаемый результат:

A.findPath (), path = {1,2,3,4,5,6,7,8,9, 10}

B.findPath (), path = {2,4,9,16,25,36,49,64,81,100}

class A 
{ 
public:
    vector<int> path;

    void addPoint(int num) {
        path.push_back(num);
    }

    vector<int> findPath() {
        for (int i = 0; i < 10; i++) {
            addPoint(i);
        }
    } 
};

class B : public A
{
public:
    void addPoint(int num) {
        path.push_back(num*num);
    }
};

В настоящий момент я копирование и вставка findPath в класс B для получения желаемого результата, но я чувствую, что должен быть более простой способ. Спасибо!

Ответы [ 2 ]

2 голосов
/ 19 июня 2020

Вам нужно использовать virtual в базовом классе. Вы также должны добавить override в производный класс, сравните CppCoreGuidelines .

class A 
{ 
public:
    ...

    virtual void addPoint(int num) {
        path.push_back(num);
    }

    ...
};

class B : public A
{
public:
    void addPoint(int num) override {
        path.push_back(num*num);
    }
};
1 голос
/ 19 июня 2020

Возможно. Это известно как шаблон метода Шаблон . Название несколько неудачное, потому что оно не имеет ничего общего с шаблонами C ++. Базовый класс может что-то реализовать, а производные классы только переопределяют отдельные шаги большего «чего-то».

Например:

struct Base {
     virtual void stepA() = 0;
     virtual void stepB() = 0;
     virtual void stepC() = 0;
     void do_something_complicated() {
          stepA();
          stepB();
          stepC();
     }
};

Производные классы только переопределяют методы для отдельных шагов, в то время как они уже составлены в базовом классе.

В вашем примере вы забыли чтобы объявить addPoint виртуальным, A должен иметь виртуальный деструктор, и рекомендуется использовать override, чтобы компилятор мог помочь вам в случае ошибок:

class A 
{ 
public:
    vector<int> path;

    virtual void addPoint(int num) {
        path.push_back(num);
    }

    vector<int> findPath() {                // () was missing
        for (int i = 0; i < 10; i++) {
            addPoint(i);
        }
        return path;                        // return was missing
    } 

    virtual ~A() = default;
};

class B : public A
{
public:
    void addPoint(int num) override {
        path.push_back(num*num);
    }
};
...