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

Виртуальный абстрактный класс

23.12.2016, 15:43. Показов 4828. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Надеюсь мой вопрос будет не глупым. Есть класс исключений в пространстве имен std
У него есть метод what
Я создаю свой базовый класс исключений, абстрактный.
В нем переопределяю функцию what.

C++
1
2
3
4
5
6
7
8
    class cError: public std::exception{
            public:
                virtual ~cErrorCan(){}
                                virtual const char* what( void ) const { return sError_.c_str(); } // Этот метод общий должен быть для всех подклассов
            protected:
                std::string sError_;
                cError();
        };
Потом конкретные классы исключений наследую от него. Вопрос. В таком случае получается класс чью реализацию они унаследуют?
Тут нужно наследовать виртуально?
C++
1
class cError:virtual public std::exception{
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
23.12.2016, 15:43
Ответы с готовыми решениями:

Виртуальный методы, абстрактный класс.
Здравствуйте. Теоретические вопросы. Что такое виртуальный методы и что такое абстрактный класс. Можете объяснить своими словами без...

Абстрактный класс. Виртуальный метод, который возвращает T- тип
Привет! Допустим, есть абстрактный класс, и метод, который возвращает T-тип. class A { public: template <class T>...

Абстрактный класс «Клиент банка», имеющий виртуальный метод для вывода данных о клиенте
Создать абстрактный класс «Клиент банка», имеющий поля ФИО и адрес, а также метод, для вывода данные по клиенту. Дочерними классами...

14
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
23.12.2016, 15:48
Цитата Сообщение от Oryel Посмотреть сообщение
абстрактный.
Он не абстрактный, у него нет чисто виртуальных функций.
Цитата Сообщение от Oryel Посмотреть сообщение
Тут нужно наследовать виртуально?
Зачем? Виртуальное наследование нужно только для решения проблемы с ромбом при множественном наследовании.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
23.12.2016, 15:48
Цитата Сообщение от Oryel Посмотреть сообщение
В таком случае получается класс чью реализацию они унаследуют?
огаа.
Цитата Сообщение от Oryel Посмотреть сообщение
Тут нужно наследовать виртуально?
нит.
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
23.12.2016, 15:52
Можно, кстати, добавить реализацию чисто виртуальной функции как вариант по умолчанию.
То есть мы будем требовать явного переопределения виртуальной функции (чтобы создать объект не абстрактного класса), но при этом наследники могут внутри метода вызывать реализацию для этой функции базового класса.
0
11 / 1 / 1
Регистрация: 02.10.2015
Сообщений: 98
23.12.2016, 15:57  [ТС]
дык.....
Абстрактный класс в объектно-ориентированном программировании — базовый класс, который не предполагает создания экземпляров
Достаточно просто конструктор кинуть в протектед. Если я не прав давай пруф, аналогично, к своему ответу требую пруф, что это не абстрактный класс.

Это вопрос с абстрактностью думаю закрыт. Отсылаю вас в гугл и в книги( тотже Страусттруп)

Вопрос у меня звучал так. std::exception - вроде не абстрактный класс. У него своя реализация метода what, я так думаю. Я унаследовал его в доругом классе. Потом еще в одном. Какую реализацию вызовет наследник?? И почему?

Даже если уйти от конкретного случая... есть класс, наследую его, переопределяю метотд. Наследую этот новый класс. Чья реализация метода вывозиться от наследника этих классов?
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
23.12.2016, 16:11
На этом моменте (чисто виртуальные функции тоже могут иметь свою реализацию), у некоторых адептов начинается диссонанс. Однако это довольно удобный приём.
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
#include <iostream>
 
struct A
{
    virtual const char* what() const = 0;
    virtual ~A() = default;
};
 
const char* A::what() const
{
    return "Default";
}
 
struct B : A
{
    const char* what() const override { return "B"; }
};
 
struct C : A
{
    const char* what() const override { return A::what(); }
};
 
int main()
{
    //A a; // error
    B b;
    C c;
    std::cout << b.what() << std::endl << c.what();
}
Добавлено через 2 минуты
Цитата Сообщение от Oryel Посмотреть сообщение
дык.....
С того самого же места:
На языке программирования C++ абстрактный класс объявляется включением хотя бы одной чистой виртуальной функции, типа virtual _сигнатура_функции_ =0;, которая, как и другие, может быть заменена.
Добавлено через 5 минут
Цитата Сообщение от Oryel Посмотреть сообщение
Чья реализация метода вывозиться от наследника этих классов?
Если методы виртуальные, то выберется последний переопределённый вариант виртуальной функции (если не указывать область видимости явно). В этом и суть виртуальных функций.

Добавлено через 5 минут
Создание объекта базового класса с конструктором в protected:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct A
{
protected:
    A() {}
};
 
struct B : A
{
    using A::A;
};
 
int main()
{
    B b;
    A a = static_cast<A>(b);
}
0
11 / 1 / 1
Регистрация: 02.10.2015
Сообщений: 98
23.12.2016, 16:15  [ТС]
Цитата Сообщение от MrGluck Посмотреть сообщение
С того самого же места:
На языке программирования C++ абстрактный класс объявляется включением хотя бы одной чистой виртуальной функции, типа virtual _сигнатура_функции_ =0;, которая, как и другие, может быть заменена.
Страуструп:
...создать абстрактный класс, объявив его кон-
структор в разделе protected. Существует другой — более распространен-
ный — способ создания абстрактного класса: указать, что одна или несколько его
виртуальных функций будет замещена в производном классе...
2 способа. Тут вопрос не копи пастить вики..а идеи...идея абстрактнго класса предоставить интерфейс. Интрефейс - не имеет реализации. А как ты это сделаешь и как удобней - твое дело. Хочешь конструктор запрети:

в с++ 11 это через delete вроде делается...тут я кидаю в протект. Вот и абстрактный класс.

Я просто в дочерних классах из -за экономии кода не хотел переопределять what. Если я бы переопределил, я бы и вопрос не задал. Вопрос в том, могу ли я наделить абстрактный класс реализацией функции и унаследовать ее?
Если да, тогда чью релазацию унаследует класс потомок Базовый класс - > Мой класс исключений -> Конкретный класс потомок, который нас интересует.)

А ваш код не отвечает на вопрос. Он дает реализацию задачи переопределения методов.. Пока что я просто переопределил в классах метод, но мне интересен такой случай наследования.
Как его граммотно реализуют..?
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
23.12.2016, 16:21
Цитата Сообщение от Oryel Посмотреть сообщение
могу ли я наделить абстрактный класс реализацией функции и унаследовать ее?
У меня как раз в примере абстрактный класс имеет реализацию чисто виртуальной функции.

Добавлено через 1 минуту
Цитата Сообщение от Oryel Посмотреть сообщение
в с++ 11 это через delete вроде делается
Но вы же сами говорите о наследовании. Такой класс просто не позволит создать потомков.
0
11 / 1 / 1
Регистрация: 02.10.2015
Сообщений: 98
23.12.2016, 16:24  [ТС]
в с++ 11 это через delete вроде делаетсяИсправляю...тут я думаю я может накосячил. на счет delete
Я поздно вообще вспомнил про это......отошел от компа...не суть. Забудем про астрактный класс

Как граммотно унаследовать такой случай, как у меня выше. Зачем потомкам переопределять метод, фактически копировать его?
C++
1
2
3
4
5
class cGeneralError : public cError{
            public:
                cGeneralError   ( const std::string &sErrString ) { sError_ = sErrString; }
                virtual const char* what( void ) const { return sError_.c_str(); }
        };
Если смысл наследования избежать копи паста.... вот и спрашиваю..как унаследовать граммотно метод и чью реализацию он вызовет

Хочу получить вот что
C++
1
2
3
4
5
class cGeneralError : public cErrorCan{
            public:
                cGeneralError   ( const std::string &sErrString ) { sError_ = sErrString; }
                // метод what наследуется от базового класса.
        };
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
23.12.2016, 16:28
Всё просто.
В потомках нужна реализация по умолчанию или переопределённая - использовать виртуальные функции.
В потомках нужно требовать явного определения метода - использовать чисто виртуальные функции. При этом можно их реализовать и использовать как реализацию по умолчанию, но требование всё равно останется.

Добавлено через 3 минуты
Цитата Сообщение от Oryel Посмотреть сообщение
Зачем потомкам переопределять метод, фактически копировать его?
Не за чем, просто не переопределяйте его и будет вызвана последняя переопределённая функция.

Кстати, можно использовать конструкторы базового класса, если новых свойств он не содержит.
С помощью ключевого слова using (С++11).
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct A
{
    int x;
    A(const int x_) : x(x_) {}
};
 
struct B : A
{
    using A::A;
};
 
int main()
{
    B b(42);
}
0
11 / 1 / 1
Регистрация: 02.10.2015
Сообщений: 98
23.12.2016, 16:30  [ТС]
Это дык понятно. Было не понятно, я бы навреное это не написал бы.
Вот я переопределил функцию член. А в std::exception или другом подобной случае есть уже свое определение функции. Чью реализацию он унаследует?
Нужно вирутальное наследование?

Добавлено через 23 секунды
Это дык понятно. Было не понятно, я бы навреное это не написал бы.
Вот я переопределил функцию член. А в std::exception или другом подобной случае есть уже свое определение функции. Чью реализацию он унаследует?
Нужно вирутальное наследование?
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
23.12.2016, 16:33
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
 
struct A
{
    virtual void foo() { std::cout << "Default\n"; }
    virtual ~A() = default;
};
 
struct B : A
{};
 
struct C: A
{
    void foo() override { std::cout << "C\n"; }
};
 
int main()
{
    B b;
    C c;
    b.foo();
    c.foo();
}
Добавлено через 1 минуту
Цитата Сообщение от Oryel Посмотреть сообщение
Чью реализацию он унаследует?
Я вам уже несколько раз писал:
Цитата Сообщение от MrGluck Посмотреть сообщение
будет вызвана последняя переопределённая функция.
Цитата Сообщение от Oryel Посмотреть сообщение
Нужно вирутальное наследование?
Опять же
Цитата Сообщение от MrGluck Посмотреть сообщение
Зачем? Виртуальное наследование нужно только для решения проблемы с ромбом при множественном наследовании.
У вас тут нет никакого множественного наследования.

Добавлено через 1 минуту
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
#include <iostream>
 
struct A
{
    virtual void foo() { std::cout << "Default\n"; }
    virtual ~A() = default;
};
 
struct B : A
{
    virtual void foo() override { std::cout << "B\n"; }
    virtual ~B() = default;
};
 
struct C: B
{};
 
struct D: C
{
    void foo() override { std::cout << "D\n"; }
};
 
int main()
{
    C c;
    D d;
    c.foo();
    d.foo();
}
0
11 / 1 / 1
Регистрация: 02.10.2015
Сообщений: 98
23.12.2016, 16:34  [ТС]
Добавлено через 48 секунд
Понятно. А где это оговоренно? что последняя переопределенная функция?
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
23.12.2016, 16:44
Лучший ответ Сообщение было отмечено Oryel как решение

Решение

Цитата Сообщение от Oryel Посмотреть сообщение
Понятно. А где это оговоренно?
В стандарте
10.3 Virtual functions
2. If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly
from Base, a member function vf with the same name, parameter-type-list (8.3.5), cv-qualification, and ref
qualifier (or absence of same) as Base::vf is declared, then Derived::vf is also virtual (whether or not it is
so declared) and it overrides113 Base::vf. For convenience we say that any virtual function overrides itself.
A virtual member function C::vf of a class object S is a final overrider unless the most derived class (1.8)
of which S is a base class subobject (if any) declares or inherits another member function that overrides vf.
In a derived class, if a virtual member function of a base class subobject has more than one final overrider
the program is ill-formed.
Добавлено через 3 минуты
Кстати, не поленился, поискал по поводу абстрактного класса:
10.4 Abstract classes
2. <...> A class is abstract if it has at least one pure virtual function.
0
11 / 1 / 1
Регистрация: 02.10.2015
Сообщений: 98
26.12.2016, 16:28  [ТС]
Эх . . . ну пусть будет так по букве стандарта. Спасибо за интересную беседу.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
26.12.2016, 16:28
Помогаю со студенческими работами здесь

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

Создать иерархию классов Figure
Создать абстрактный базовый класс Figure с виртуальными методами вычисления площади и периметра. Создать производные классы: Rectangle...

Абстрактный класс, наследование, класс хранится в другом классе
Нужна помощь. Написать программу: 1 класс. Имеется абстрактный класс который описывает какую-то сущность, например Человек. В абстрактном...

Создать абстрактный базовый класс Тройка чисел с виртуальными методами увеличения на 1. Создать производный класс Время со своими функциями
Здравствуйте, пожалуйста помогите написать код к данной задаче, с таким условием: Создать абстрактный базовый класс Тройка чисел с...

Написать обработчик исключений ситуации при преобразовании указателя на класс B до указателя на абстрактный класс А ...
Написать обработчик исключений ситуации при преобразовании указателя на класс B до указателя на абстрактный класс А ... как сделать...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
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. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru