Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.64/11: Рейтинг темы: голосов - 11, средняя оценка - 4.64
 Аватар для Nishen
1357 / 856 / 365
Регистрация: 26.02.2015
Сообщений: 3,814

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

17.03.2015, 20:19. Показов 2048. Ответов 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
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
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
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
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
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
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
Ответ Создать тему
Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru