Аватар для Nishen
1357 / 856 / 365
Регистрация: 26.02.2015
Сообщений: 3,814

Абстрактные классы и чистые виртуальные функции

17.03.2015, 20:19. Показов 2038. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
У Р. Лафоре написано:
Как только в базовом классе окажется чистая виртуальная функция, необходимо будет позаботиться о том, чтобы избежать ее употребления во всех производных классах, которые вы собираетесь реализовать. Если класс использует чистую виртуальную функцию, он сам становится абстрактным, никакие объекты из него реализовать не удастся (производные от него классы, впрочем, уже не имеют этого ограничения).
И вот, есть такой пример из его книги:
Кликните здесь для просмотра всего текста
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <iostream>
#include "msoftcon.h"
using namespace std;
 
//---------------------------------------------------------------------------//
//Определение базового класса Shape
//---------------------------------------------------------------------------//
class Shape{
    protected:
        int xCo, yCo;
        color fillcolor;
        fstyle fillstyle;
    public:
        Shape() : xCo(0), yCo(0), fillcolor(cWHITE), fillstyle(SOLID_FILL){
        }
        Shape(int x, int y, color fc, fstyle fs) : xCo(x), yCo(y), fillcolor(fc), fillstyle(fs){
        }
        virtual void draw() const = 0 {
            set_color(fillcolor);
            set_fill_style(fillstyle);
        }
};
//---------------------------------------------------------------------------//
//Определение производного от Shape класса Ball
//---------------------------------------------------------------------------//
class Ball : public Shape{
    private:
        int radius;
    public:
        Ball() : Shape(), radius(0){
        }
        Ball(int x, int y, int r, color fc, fstyle fs) : Shape(x, y, fc, fs), radius(r){
        }
        void draw() const{
            Shape::draw();
            draw_circle(xCo, yCo, radius);
        }
};
//---------------------------------------------------------------------------//
//Определение производного от Shape класса Rect
//---------------------------------------------------------------------------//
class Rect : public Shape{
    private:
        int width, height;
    public:
        Rect() : Shape(), height(0), width(0){
        }
        Rect(int x, int y, int h, int w, color fc, fstyle fs) : Shape(x, y, fc, fs),
            height(h), width(w){
        }
        void draw() const{
            Shape::draw();
            draw_rectangle(xCo, yCo, xCo + width, yCo + height);
            set_color(cWHITE);
            draw_line(xCo, yCo, xCo + width, yCo + height);
        };
};
//---------------------------------------------------------------------------//
//Определение производного от Shape класса Tria
//---------------------------------------------------------------------------//
class Tria : public Shape{
    private:
        int height;
    public:
        Tria() : Shape(), height(0){
        }
        Tria(int x, int y, int h, color fc, fstyle fs) : Shape(x, y, fc, fs),
            height(h){
        }
        void draw() const{
            Shape::draw();
            draw_pyramid(xCo, yCo, height);
        }
};
 
int main(){
    init_graphics();
    Shape* pShapes[3];
    pShapes[0] = new Ball(40, 12, 5, cBLUE, X_FILL);
    pShapes[1] = new Rect(12, 7, 10, 15, cRED, SOLID_FILL);
    pShapes[2] = new Tria(60, 7, 11, cGREEN, MEDIUM_FILL);
    for(int j = 0; j < 3; j++){
        pShapes[j]->draw();
    }
    for(int j = 0; j < 3; j++){
        delete pShapes[j];
    }
    set_cursor_pos(1, 25);
    system("PAUSE");
    return 0;
}


В данном примере определена чистая виртуальная функция в базовом классе:
C++
1
2
3
4
        virtual void draw() const = 0 {
            set_color(fillcolor);
            set_fill_style(fillstyle);
        }
Которая затем используется в наследуемых классах:
C++
1
2
3
4
        void draw() const{
            Shape::draw();
            draw_circle(xCo, yCo, radius);
        }
И при этом я могу создавать объекты производных классов, хотя говорилось, что он станет абстрактным и реализовывать объекты класса будет нельзя:
C++
1
pShapes[0] = new Ball(40, 12, 5, cBLUE, X_FILL);
Объясните, пожалуйста?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
17.03.2015, 20:19
Ответы с готовыми решениями:

Наследование: Чистые Виртуальные функции и Абстрактные классы
Добрый вечер помогите пожалуйста вывести на экран то что мы вводим с клавиатуры ( int s , char d ) #include...

Виртуальные функции и абстрактные классы
Есть два класса: Человек и производный от него Совершеннолетний. 1) Как сделать чтобы у класса Совершеннолетний функции void...

Виртуальные функции. Абстрактные классы.
Есть у меня абстрактный класс class DataManager { protected: Configuration configuration; public:...

6
19483 / 10091 / 2457
Регистрация: 30.01.2014
Сообщений: 17,796
17.03.2015, 20:29
Цитата Сообщение от Nishen Посмотреть сообщение
Объясните, пожалуйста?
Производный класс станет абстрактным, если он не реализует чистовиртуальную функцию у себя. В этом примеры все классы реализуют функцию draw. Поэтому любой наследник можно сконструировать.

А вот что тут действительно неправильно, так это возможность реализации тела чистовиртуальной функции в теле класса. Такое запрещено правилами языка. (Да, VS компилирует, я в курсе, но это исключительно его вольность, а вот Лафоре поощряет это, давая такие сомнительные примеры )
1
 Аватар для Nishen
1357 / 856 / 365
Регистрация: 26.02.2015
Сообщений: 3,814
17.03.2015, 20:35  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Производный класс станет абстрактным, если он не реализует чистовиртуальную функцию у себя.
Это сообщение ввело меня в еще большее заблуждение. Я совсем запутался. Можете пояснить?

Добавлено через 3 минуты
Цитата Сообщение от DrOffset Посмотреть сообщение
А вот что тут действительно неправильно, так это возможность реализации тела чистовиртуальной функции в теле класса.
Нужно было так:
C++
1
2
3
4
5
6
7
class A:{
    public:
        virtual void draw() const = 0;
};
virtual void A::draw() const = 0{
    //тело функции
}
0
19483 / 10091 / 2457
Регистрация: 30.01.2014
Сообщений: 17,796
17.03.2015, 20:45
Цитата Сообщение от Nishen Посмотреть сообщение
Это сообщение ввело меня в еще большее заблуждение.
Ну ты соотнеси то, что написано, с тем, что ты видишь в коде. Есть базовый класс, у него есть чистовиртуальная функция. Если у него есть наследники, они обязаны предоставить свою реализацию этой функции, иначе они тоже останутся абстрактными. У каждого из наследников в том примере такая реализация есть. Реализация функции draw (сейчас ты смотришь на содержимое наследников).
1
 Аватар для Nishen
1357 / 856 / 365
Регистрация: 26.02.2015
Сообщений: 3,814
17.03.2015, 20:50  [ТС]
Цитата Сообщение от Nishen Посмотреть сообщение
Нужно было так:
Нет, нужно так:
C++
1
2
3
4
5
6
7
class A:{
    public:
        virtual void draw() const = 0;
};
void A::draw() const{
    //тело функции
}
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
17.03.2015, 20:52
Цитата Сообщение от DrOffset Посмотреть сообщение
А вот что тут действительно неправильно, так это возможность реализации тела чистовиртуальной функции в теле класса.
А вне тела класса разве можно такое делать?
0
19483 / 10091 / 2457
Регистрация: 30.01.2014
Сообщений: 17,796
17.03.2015, 21:14
Цитата Сообщение от castaway Посмотреть сообщение
А вне тела класса разве можно такое делать?
Можно.

Добавлено через 9 минут
10.4/2
A pure virtual function need be defined only if called with, or as if with (12.4), the qualified-id syntax
12.4/9
A destructor can be declared virtual (10.3) or pure virtual (10.4); if any objects of that class or any
derived class are created in the program, the destructor shall be defined. If a class has a base class with a
virtual destructor, its destructor (whether user- or implicitly-declared) is virtual.
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
17.03.2015, 21:14
Помогаю со студенческими работами здесь

Абстрактные классы, виртуальные функции
Собственно сабж. нужна достаточно простая(не важно что выполняющая) программа с использованием абстрактных классов и виртуальных функций,...

Абстрактные классы. Виртуальные функции
Помогите, пожалуйста. Класс : место - область - город - мегаполис 1. Определить иерархию системы, которая заключается в...

Абстрактные классы. Виртуальные функции. Задача
ПОМОГИТЕ ПОЖАЛУЙСТА РЕШИТЬ ЗАДАЧУ: #include&lt;stdio.h&gt; #include&lt;conio.h&gt; #include&lt;locale.h&gt; #include&lt;time.h&gt; ...

Виртуальные абстрактные базовые классы
Привет всем!:-) Вчера столкнулся со следующей проблемой: компилятор ругается на чистый виртуальный деструктор. Собственно листинги: ...

Шаблонные чистые виртуальные методы
Возник вопрос: Есть у нас допустим класс, который мы желаем сделать абстрактным: template &lt;typename T, class = typename...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

Новые блоги и статьи
Мысли в слух
kumehtar 07.11.2025
Заметил среди людей, что по-настоящему верная дружба бывает между теми, с кем нечего делить.
Новая зверюга
volvo 07.11.2025
Подарок на Хеллоуин, и теперь у нас кроме Tuxedo Cat есть еще и щенок далматинца: Хочу еще Симбу взять, очень нравится. . .
Инференс ML моделей в Java: TensorFlow, DL4J и DJL
Javaican 05.11.2025
Python захватил мир машинного обучения - это факт. Но когда дело доходит до продакшена, ситуация не так однозначна. Помню проект в крупном банке три года назад: команда data science натренировала. . .
Mapped types (отображённые типы) в TypeScript
Reangularity 03.11.2025
Mapped types работают как конвейер - берут существующую структуру и производят новую по заданным правилам. Меняют модификаторы свойств, трансформируют значения, фильтруют ключи. Один раз описал. . .
Адаптивная случайность в Unity: динамические вероятности для улучшения игрового дизайна
GameUnited 02.11.2025
Мой знакомый геймдизайнер потерял двадцать процентов активной аудитории за неделю. А виновником оказался обычный генератор псевдослучайных чисел. Казалось бы - добавил в карточную игру случайное. . .
Протоколы в Python
py-thonny 31.10.2025
Традиционная утиная типизация работает просто: попробовал вызвать метод, получилось - отлично, не получилось - упал с ошибкой в рантайме. Протоколы добавляют сюда проверку на этапе статического. . .
C++26: Read-copy-update (RCU)
bytestream 30.10.2025
Прошло почти двадцать лет с тех пор, как производители процессоров отказались от гонки мегагерц и перешли на многоядерность. И знаете что? Мы до сих пор спотыкаемся о те же грабли. Каждый раз, когда. . .
Изображения webp на старых x32 ОС Windows XP и Windows 7
Argus19 30.10.2025
Изображения webp на старых x32 ОС Windows XP и Windows 7 Чтобы решить задачу, использовал интернет: поисковики Google и Yandex, а также подсказки Deep Seek. Как оказалось, чтобы создать. . .
Passkey в ASP.NET Core identity
stackOverflow 29.10.2025
Пароли мертвы. Нет, серьезно - я повторяю это уже лет пять, но теперь впервые за это время чувствую, что это не просто красивые слова. В . NET 10 команда Microsoft внедрила поддержку Passkey прямо в. . .
Последние результаты исследования от команды MCM (октябрь 2025 г.)
Programma_Boinc 29.10.2025
Последние результаты исследования от команды MCM (октябрь 2025 г. ) Поскольку мы продолжаем изучать гены, которые играют ведущую роль в развитии рака, в рамках проекта "Картирование раковых. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru