Производный класс не может вызвать свой собственный метод?

#include <iostream>
#include "memory"

// base class
class base
{
public:
    void setVal(int val)
    {
        m_val = val;
    }

    int getVal()
    {
        std::cout << "val = " <<m_val<<std::endl;
        return m_val;
    }

    bool checkVal(int val)
    {
        return val>8?true : false;
    }
    
private:
    int m_val = 5;
};

// derived class
class derived1: public base
{
private:
};

// derived class
class derived2: public base
{
public:
    bool checkd2Val()
    {
        checkVal(9);
    }
private:
};


int main()
{
    std::unique_ptr<base> d1;
    d1 = std::make_unique<derived1>();

    std::unique_ptr<base> d2;
    d2 = std::make_unique<derived2>();

    d2->checkd2Val(7);

    return 0;
}

Компилятор выдает ошибку: No member named "checkd2Val" in base. Мне интересно, как нам вызвать checkd2Val в этом случае? Спасибо!!

Переменная d2 имеет тип base *. У класса base нет метода checkd2Val(), поэтому d2 не может получить к нему доступ. Указатели на класс base могут иметь доступ только к общедоступным вещам в классе base.

Thomas Matthews 03.09.2024 23:50

Вот вам тест: derived2 d3; d3.checkd2Value(42);. Это должно доказать, что производные классы могут получать доступ к методам, которых нет в базовом классе.

Thomas Matthews 03.09.2024 23:52
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ошибка правильная. Вы пытаетесь вызвать checkd2Val(), используя указатель base*, а checkd2Val() не существует в классе base.

Если вам действительно нужно вызвать checkd2Val() с помощью d2, вам нужно ввести его, например:

static_cast<derived2*>(d2.get())->checkd2Val(7);

Однако это все равно не удастся, поскольку derived2::checkd2Val() не принимает входной параметр, а main() передает значение.

Вместо этого вам следует объявить base::checkVal() как virtual и переопределить его derived2, например:

#include <iostream>
#include <memory>

// base class
class base
{
public:
    void setVal(int val)
    {
        m_val = val;
    }

    int getVal()
    {
        std::cout << "val = " <<m_val<<std::endl;
        return m_val;
    }

    virtual bool checkVal(int val)
    {
        return val > 8;
    }
    
private:
    int m_val = 5;
};

// derived class
class derived2: public base
{
public:
    bool checkVal(int val) override
    {
        return base::checkVal(9);
    }
};

int main()
{
    std::unique_ptr<base> d2 = std::make_unique<derived2>();
    d2->checkVal(7);

    return 0;
}

Другие вопросы по теме