Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
Nishen
538 / 342 / 180
Регистрация: 26.02.2015
Сообщений: 1,588
Завершенные тесты: 3
1

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

17.03.2015, 20:19. Просмотров 902. Ответов 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.03.2015, 20:19
Ответы с готовыми решениями:

Наследование: Чистые Виртуальные функции и Абстрактные классы
Добрый вечер помогите пожалуйста вывести на экран то что мы вводим с клавиатуры...

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

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

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

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

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

А вот что тут действительно неправильно, так это возможность реализации тела чистовиртуальной функции в теле класса. Такое запрещено правилами языка. (Да, VS компилирует, я в курсе, но это исключительно его вольность, а вот Лафоре поощряет это, давая такие сомнительные примеры )
1
Nishen
538 / 342 / 180
Регистрация: 26.02.2015
Сообщений: 1,588
Завершенные тесты: 3
17.03.2015, 20:35  [ТС] 3
Цитата Сообщение от 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
DrOffset
8928 / 4809 / 1176
Регистрация: 30.01.2014
Сообщений: 7,848
17.03.2015, 20:45 4
Цитата Сообщение от Nishen Посмотреть сообщение
Это сообщение ввело меня в еще большее заблуждение.
Ну ты соотнеси то, что написано, с тем, что ты видишь в коде. Есть базовый класс, у него есть чистовиртуальная функция. Если у него есть наследники, они обязаны предоставить свою реализацию этой функции, иначе они тоже останутся абстрактными. У каждого из наследников в том примере такая реализация есть. Реализация функции draw (сейчас ты смотришь на содержимое наследников).
1
Nishen
538 / 342 / 180
Регистрация: 26.02.2015
Сообщений: 1,588
Завершенные тесты: 3
17.03.2015, 20:50  [ТС] 5
Цитата Сообщение от Nishen Посмотреть сообщение
Нужно было так:
Нет, нужно так:
C++
1
2
3
4
5
6
7
class A:{
    public:
        virtual void draw() const = 0;
};
void A::draw() const{
    //тело функции
}
0
castaway
Эксперт С++
4934 / 3039 / 455
Регистрация: 10.11.2010
Сообщений: 11,119
Записей в блоге: 10
Завершенные тесты: 1
17.03.2015, 20:52 6
Цитата Сообщение от DrOffset Посмотреть сообщение
А вот что тут действительно неправильно, так это возможность реализации тела чистовиртуальной функции в теле класса.
А вне тела класса разве можно такое делать?
0
DrOffset
8928 / 4809 / 1176
Регистрация: 30.01.2014
Сообщений: 7,848
17.03.2015, 21:14 7
Цитата Сообщение от 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
17.03.2015, 21:14
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.03.2015, 21:14

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

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

Шаблонные чистые виртуальные методы
Возник вопрос: Есть у нас допустим класс, который мы желаем сделать...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru