Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/9: Рейтинг темы: голосов - 9, средняя оценка - 4.89
1 / 1 / 0
Регистрация: 16.01.2016
Сообщений: 43

C++ наследование классов

02.03.2020, 10:29. Показов 2017. Ответов 13

Студворк — интернет-сервис помощи студентам
Есть класс Parent, у которого три метода: a(), b() и c(). Метод a() вызывает методы b() и c().
Класс Child наследуется от Parent, и в нём переопределяется метод c(). Проблема в том, что если не переопределять метод a() в дочернем классе, то он также будет вызывать c() родительского класса, что с этим можно сделать?
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
02.03.2020, 10:29
Ответы с готовыми решениями:

Автоматическая генерация классов С ++ с UML диаграмм классов. Наследование в с++. Абстрактные классы. WhiteStarUML
Создать классовую модель(желательно в WhiteStarUML), которая включает в себя абстрактный класс CGraphicsObject, его наследник - базовый...

Заменить наследование классов на наследование интерфейсов
#include <iostream> #include <assert.h> using namespace std; int people_on_base = 100; int vehicles_on_base = 100; double...

Наследование классов. Копирование производных классов
Здравствуйте всем, у меня такой вопрос: написал код #include "stdafx.h" class A //Создаем класс А { int mA; ...

13
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
02.03.2020, 10:48
Цитата Сообщение от Coi Посмотреть сообщение
Класс Child наследуется от Parent, и в нём переопределяется метод c(). Проблема в том, что если не переопределять метод a() в дочернем классе, то он также будет вызывать c() родительского класса, что с этим можно сделать?
Ничего, это так и задумано.
А чем тебя не устраивает, что вызывается метод родительского класса?
Там не только виртуальные, обычные методы тоже будут вызываться из класса Parent, если ты не переопределишь их в классе Child
0
1 / 1 / 0
Регистрация: 16.01.2016
Сообщений: 43
02.03.2020, 11:01  [ТС]
Я не сильно с классами пока. У меня есть метод в родительском классе, в котором также вызываются методы (условно, определить позицию кнопок, кол-во кнопок, отрисовку и т.д). Я делаю дочерний класс, переопределяют позицию и кол-во кнопок, но не переопределяю метод, в котором этом всё вызывается, и он вызывает не переопределенный методы, а методы родительского класса. Не устраивает тем, что ничего не меняется, и тогда мне по сути надо нажать ctrl+c и ctrl+v и сделать класс с нуля.
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
02.03.2020, 11:03
Цитата Сообщение от Coi Посмотреть сообщение
Я делаю дочерний класс, переопределяют позицию и кол-во кнопок, но не переопределяю метод, в котором этом всё вызывается, и он вызывает не переопределенный методы, а методы родительского класса.
Покажи-ка код. Если у тебя всё правильно, то там должны вызываться переопределённые виртуальные методы.
0
1 / 1 / 0
Регистрация: 16.01.2016
Сообщений: 43
02.03.2020, 11:15  [ТС]
Это родительский (hpp, то есть я тут ничего не определяю):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class Test {
public:
    Test(sf::RenderWindow& window);
    void run_Test(sf::RenderWindow& window);
    private:
    void draw(); // отрисовка
    void set_checkbox(); // настройка чекбоксов (позиция)
    void handle_input(); // обработка ввода
    void set_text(); // 
    void set_choice(); // логика выбора чекбоксов
    void next_actions(); // действия, при нажатии на "далее"
    void text_from_file(std::string file, int n, int type = 0); // функция, получающая вопросы из файла
    void mouse_in(); // курсор мыши на кнопке?
    void print_result(); // результаты, после прохождения теста
 
protected:
    int target; // отслеживание наведения мыши на кнопки
    int choice; // отслеживание клика по кнопке
    bool next; // триггер нажатия на далее
    int count; // Да - +1 Нет - -1
    int ask_num; // номер текущего вопроса
 
    sf::String str;
    sf::String rez;
    sf::RenderWindow& m_window;
    sf::Mouse m_mouse;
    std::vector <sf::String> questions;
    std::vector <sf::String> results;
    sf::Font m_font;
    sf::Text m_text;
    sf::Text text_box;
 
    // чекбоксы и кнопка
    sf::Texture check_button, uncheck_button, continue_button;
    sf::Sprite check1, check2, check3, check4, check5, c_button;
    bool isTest;
 
};
void start_t(sf::RenderWindow& window);
Это определенный методы из родительского:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void Test::run_Test(sf::RenderWindow& window) {
    int trigger = 0;
    while (isTest) {
        mouse_in();
        handle_input();
        set_choice();
        if(ask_num < N) next_actions(); 
        draw();
        target = 0;
        if (ask_num >= N && trigger == 0) {
            print_result();
            trigger++;
        }
    }
}
// вот его я и хочу переопределить
void Test::set_choice() {
    if (choice == 1) check1.setTexture(check_button);
    else check1.setTexture(uncheck_button);
    if (choice == 2) check2.setTexture(check_button);
    else check2.setTexture(uncheck_button);
    if (choice == 3) check3.setTexture(check_button);
    else check3.setTexture(uncheck_button);
    c_button.setTexture(continue_button);
}
Наследую класс:
C++
1
2
3
4
5
6
7
8
class second_Test : public Test {
public:
    second_Test(sf::RenderWindow& window) : Test(window) {}
private:
    void set_checkbox();
    void set_choice();
};
void start_second_test(sf::RenderWindow& window);
Переопределяю метод, но дополнительные чекбоксы не появляются (если я еще и run_Test переопределяю, тогда норм):
C++
1
2
3
4
5
6
7
8
9
10
void second_Test::set_checkbox() {
    check1.setPosition(200, 350);
    check2.setPosition(300, 350);
    check3.setPosition(400, 350);
    c_button.setPosition(350, 440);
    text_box.setPosition(290, 400);
    check4.setPosition(500, 350);
    check5.setPosition(600, 350);
    text_box.setString(L"1\t\t2\t\t3\t\t4\t\t5");
}
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9006 / 4707 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
02.03.2020, 11:15
Цитата Сообщение от Coi Посмотреть сообщение
Проблема в том, что если не переопределять метод a() в дочернем классе, то он также будет вызывать c() родительского класса, что с этим можно сделать?
Если а вызывает с то с это часть реализации а. Нельзя пилить свою ногу и надеяться на лучшее. Либо не трогайте с, либо переопределяйте и а.
1
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
02.03.2020, 11:21
Лучший ответ Сообщение было отмечено Coi как решение

Решение

Цитата Сообщение от Coi Посмотреть сообщение
// вот его я и хочу переопределить
void Test::set_choice() {
Методы, которые ты хочешь переопределить должны быть виртуальными, в классе Test
C++
1
2
virtual void set_checkbox(); // настройка чекбоксов (позиция)
virtual void set_choice(); // логика выбора чекбоксов
Добавлено через 1 минуту
C++
1
2
3
4
5
6
7
class second_Test : public Test {
public:
    second_Test(sf::RenderWindow& window) : Test(window) {}
private:
    virtual void set_checkbox() override;
    virtual void set_choice() override;
};
1
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
02.03.2020, 11:22
Цитата Сообщение от IGPIGP Посмотреть сообщение
Либо не трогайте с, либо переопределяйте и а.
При открытом наследовании переопределять не виртуальные функции не рекомендуется. Ибо открытое наследование гласит,
«является разновидностью», а объявление не виртуальной функции в классе определяет инвариант относительно специализации этого класса.
1
1 / 1 / 0
Регистрация: 16.01.2016
Сообщений: 43
02.03.2020, 11:25  [ТС]
Спасибо) Теперь работает, осталось только почитать про virtual и override)
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
02.03.2020, 11:38
Цитата Сообщение от Coi Посмотреть сообщение
Спасибо) Теперь работает, осталось только почитать про virtual и override)
override означает, что метод обязательно должен быть объявлен в базовом классе как вирутальный. Иначе легко ошибиться, например изменив параметр - в результате получится совсем другой метод.

Добавлено через 9 минут
Coi, кстати, не забудь сделать для класса Test виртульный деструктор, чтоб потом не искать утечки памяти
C++
1
2
3
4
5
6
class Test {
public:
    Test(sf::RenderWindow& window);
   virtual ~Test()
   {
   }
1
 Аватар для Annemesski
2673 / 1335 / 480
Регистрация: 08.11.2016
Сообщений: 3,690
02.03.2020, 11:42
Coi, virtual - указывает на то, что метод виртуальный, то есть может быть (или должен быть, если это чисто виртуальный (абстрактный) метод объявленный как virtual TYPE Foo(arsg...) = 0;) переопределен в производном классе.

override - инструкция указывающая компилятору что это именно переопределенный метод, если не использовать эту инструкцию, то есть риск что вместо переопределения метода родителя объявите новый метод с другим именем в виду банальной опечатки (передаваемые параметры также относятся к имени метода).

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
calss Base
{
public:
//...............
protected:
 virtual void MyVeryLongButInfomationfullMethodName(void) {};
};
 
class Foo : public Base
{
public:
//............
protected:
 virtual void MyVeryLongButInfomationfullMetodName(void) {}; //объявили новый метод в виду ошибки Mrthod в Base, а тут Metod.
 virtual void MyVeryLongButInfomationfullMetodName(void) override {}; // компилятор сообщит что такого метода нет
};
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9006 / 4707 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
02.03.2020, 12:19
Цитата Сообщение от _stanislav Посмотреть сообщение
При открытом наследовании переопределять не виртуальные функции не рекомендуется. Ибо открытое наследование гласит,
«является разновидностью», а объявление не виртуальной функции в классе определяет инвариант относительно специализации этого класса.
А где у ТС о том, что он переопределяет не виртуальные функции? _stanislav, о чём речь? Там сказано, я переопределил метод, который вызывается в методе который я не переопределял. Но этот метод тоже меняет поведение. Как разрешить вопрос. Я же не про методы а про органы писал. Про ногу, если точнее.

Добавлено через 1 минуту
Цитата Сообщение от _stanislav Посмотреть сообщение
При открытом наследовании переопределять не виртуальные функции не рекомендуется.
А при закрытом?
0
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
02.03.2020, 12:35
Цитата Сообщение от IGPIGP Посмотреть сообщение
А при закрытом?
При наследовании реализации, можно. Так как производный класс уже не будет разновидностью базового и компиляторы не будут его не явно приводить к базовому.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9006 / 4707 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
02.03.2020, 13:02
Цитата Сообщение от _stanislav Посмотреть сообщение
При наследовании реализации, можно. Так как производный класс уже не будет разновидностью базового и компиляторы не будут его не явно приводить к базовому.
А к вопросу ТС оно относится? Смотри:
Цитата Сообщение от Coi Посмотреть сообщение
Есть класс Parent, у которого три метода: a(), b() и c(). Метод a() вызывает методы b() и c().
Класс Child наследуется от Parent, и в нём переопределяется метод c(). Проблема в том, что если не переопределять метод a() в дочернем классе, то он также будет вызывать c() родительского класса, что с этим можно сделать?
Тут же всё написано.
Цитата Сообщение от Coi Посмотреть сообщение
Проблема в том, что если не переопределять метод a() в дочернем классе, то он также будет вызывать c() родительского класса
Я и написал то, что написал. В данном разе не важно какую логическую ошибку или уязвимость архитектуры провоцирует ТС. Родительский метод который вызывает переопределяемый (не важно виртуальный ли первый), обязательно изменит поведение. Родитель о наследнике ничего не знает. Следовательно придётся исправлять ситуацию переписывая и первый метод. В CRTP у родителя есть информация о реализации потомка, но речь то была о простом наследовании, как я понял.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
02.03.2020, 13:02
Помогаю со студенческими работами здесь

наследование классов
Помогите пожалуйста разобраться с задачей Создайте базу данных деканата. В ней фиксируются данные о 2 категориях студентах: студенты...

Наследование классов
Помогите, пожалуйста, разобраться - необходимо написать класс Administrator, кот наследуется (is derived) из класса SalariedEmployee: ...

наследование классов
Работаю в с++ билдер.. программа вылетает при запуске.. после того, как сделал наследование.. В чем проблема? Как решить? Вот код: ...

Наследование классов
#include &lt;iostream&gt; #include &lt;conio.h&gt; using namespace std; const int LEN=80; class kraina { private: ...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru