Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 284, средняя оценка - 4.76
BTR
8 / 8 / 1
Регистрация: 01.11.2010
Сообщений: 157
#1

абстрактный класс - C++

12.01.2011, 20:42. Просмотров 41756. Ответов 12
Метки нет (Все метки)

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

Добавлено через 21 минуту
а то просто не всегда понимаю по своей книжке что написано, а вот денег на новую нету
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.01.2011, 20:42
Здравствуйте! Я подобрал для вас темы с ответами на вопрос абстрактный класс (C++):

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

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

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

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

Абстрактный класс/Класс интерфейс - C++
Не ловлю суть в чем разница между интерфейсом и абстрактным классом. И там и там у методов нету реализации. Ну интерфейс задает набор...

Создать класс - данные - абстрактный базовый класс. Создать производные классы - C++
Всем привет! У меня вот такая проблема.... Создать класс - данные - абстрактный базовый класс. Создать производные классы - данные типа...

12
silent_1991
Эксперт С++
4997 / 3055 / 149
Регистрация: 11.11.2009
Сообщений: 7,040
Завершенные тесты: 1
12.01.2011, 21:03 #2
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
BTR, абстрактный класс - это класс, экземпляры которого не могут быть созданы. Самый распространённый пример - геометрические фигуры. Вы ведь не можете создать экземпляр типа "фигура". Это слишком абстрактно, не хватает конкретики. Однако от фигуры могут наследоваться конкретные формы - круг, квадрат, треугольник и т.д. Вот их экземпляры создать уже можно.
Везде пишут о чисто виртуальных функциях, потому что абстрактным может являться только класс, который содержит как минимум одну чисто виртуальную функцию (т.е. функцию, реализация которой в данном классе не предполагается, а предполагается в классах-наследниках). Приведу пример кода с той же фигурой:

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
#include <iostream>
 
class Shape
{
public:
    virtual double area() const = 0;
};
 
class Square: public Shape
{
public:
    Square(double a = 1): _a(a) { }
 
    virtual double area() const { return _a * _a; }
 
private:
    double _a;
};
 
class Circle: public Shape
{
public:
    Circle(double r = 1): _r(r) { }
 
    virtual double area() const { return 3.14159265358 * _r * _r; }
 
private:
    double _r;
};
 
int main()
{
    Shape *shapes[5];
 
    shapes[0] = new Circle (3);
    shapes[1] = new Square (2);
    shapes[2] = new Square (2.5);
    shapes[3] = new Circle (5);
    shapes[4] = new Circle (10);
 
    for (int i = 0; i < 5; ++i)
        std::cout << shapes[i]->area() << std::endl;
 
    for (int i = 0; i < 5; ++i)
        delete shapes[i];
 
    return 0;
}
Как видите, класс Shape - абстрактный, поскольку там объявлена чисто виртуальная функция area (мы ведь не можем вычислить площадь какой-то абстрактной фигуры...). Зато в классах, которые наследуют от Shape - Circle и Square функция area уже имеет определение. Затем, в главной функции, создаётся массив указателей на Shape (в отличие от экземпляров абстрактного класса, создавать указатели на него мы можем). Затем каждый указатель инициализируется конкретным объектом - кругом или квадратом (поскольку указатель на базовый класс является также указателем на любой производный класс). И затем, в цикле, не задумываясь, в какой ячейке массива какой объект находится, мы просто вызываем для каждого его метод area, а он для каждого объекта выполнит свои действия. Это очень удобно, когда заранее не известно, на какой объект будет указывать очередной указатель (скажем, пользователь сам выбирает, какую фигуру надо создать). Называется это поздним (или динамическим) связыванием.
32
BTR
8 / 8 / 1
Регистрация: 01.11.2010
Сообщений: 157
12.01.2011, 21:16  [ТС] #3
что то на счет объявления объекта в вашем коде не понял, раз класс Shape абстрактный, то как вы его значения даете объекту, попросту говоря как из него вы делаете объект, растолкуйте пожалуйста, заранее благодарен
0
sandye51
программист С++
686 / 588 / 39
Регистрация: 19.12.2010
Сообщений: 2,016
12.01.2011, 21:22 #4
BTR, проще говоря, указатель на базовый класс могут указывать на объекты любых отнаследованных от него классов;
1
BTR
8 / 8 / 1
Регистрация: 01.11.2010
Сообщений: 157
12.01.2011, 21:27  [ТС] #5
Цитата Сообщение от sandye51 Посмотреть сообщение
BTR, проще говоря, указатель на базовый класс могут указывать на объекты любых отнаследованных от него классов;
я немного не понял что вы сказали, пожалуйста перефразируйте предложение, если Вам не сложно, благодарю! =)

Добавлено через 1 минуту
я не понял именно почему ошибка не выдается при объявлении объекта абстрактного класса, вот что мне не понятно, можете объяснить?
0
silent_1991
Эксперт С++
4997 / 3055 / 149
Регистрация: 11.11.2009
Сообщений: 7,040
Завершенные тесты: 1
12.01.2011, 21:28 #6
BTR, именно на абстрактный класс мы создаём только лишь указатели (это не возбраняется), а конкретные значения присваиваем от унаследованных от абстрактного классов (которые являются конкретными и экземпляры которых мы уже можем объявить без проблем).
1
BTR
8 / 8 / 1
Регистрация: 01.11.2010
Сообщений: 157
12.01.2011, 21:33  [ТС] #7
а зачем нужен такой тип Shape*, что он дает, как им пользоваться? Скажите пожалуйста

Добавлено через 1 минуту
аааааа, все я догнал!!!!!!! Shape это базовый тип, что бы можно было присвоить этому массиву значение других объектов классов нужно объявить массив с типом Shape* потому что это базовый класс всех подклассов

Добавлено через 37 секунд
правильно я мыслю?
0
silent_1991
Эксперт С++
4997 / 3055 / 149
Регистрация: 11.11.2009
Сообщений: 7,040
Завершенные тесты: 1
12.01.2011, 21:38 #8
Это указатель на Shape. Хоть Shape и является абстрактным, это не отменяет других его свойств, как класса. В частности, этому указателю можно присвоить как адрес объекта типа Shape, так и адрес любого объекта, класс которого наследует от Shape (если вы добрались до абстрактных классов, это вы уже должны знать, об этом говорится в самом начале изучения наследования в любой книге). Поскольку Shape - абстрактный класс, то его экземпляр мы создать не можем, а значит, никакого адреса экземпляра класса Shape быть не может. Значит, остаются только экземпляры классов, которые наследуют от Shape. Чем мы, собственно, и пользуемся, присваивая указателю на Shape адрес объекта класса Circle или Square.

Добавлено через 1 минуту
BTR, да, всё верно)))
2
BTR
8 / 8 / 1
Регистрация: 01.11.2010
Сообщений: 157
12.01.2011, 21:44  [ТС] #9
спасибо, если кто-то тут изучает PHP и у него ничего не получается, обращайтесь, я помогу, всем спасибо
0
RASHFor
6 / 6 / 0
Регистрация: 12.02.2012
Сообщений: 224
18.03.2013, 15:16 #10
Извините,а что означает строчка
C++
1
 Square(double a = 1): _a(a) { }
Конструктор ?
0
silent_1991
Эксперт С++
4997 / 3055 / 149
Регистрация: 11.11.2009
Сообщений: 7,040
Завершенные тесты: 1
18.03.2013, 15:45 #11
RASHFor, да. Конструктор с одним параметром по умолчанию (может быть вызван с одним параметром типа double или типа, который компилятор может автоматически привести к double, или же без параметров, что будет эквивалентно вызову его с одним параметром - единицей), который посредством списка инициализации инициализирует поле _a значением параметра конструктора a.
3
zybrzybr
17 / 16 / 0
Регистрация: 29.09.2010
Сообщений: 156
29.07.2013, 04:08 #12
Цитата Сообщение от silent_1991 Посмотреть сообщение
BTR, абстрактный класс - это класс, экземпляры которого не могут быть созданы. Самый распространённый пример - геометрические фигуры. Вы ведь не можете создать экземпляр типа "фигура". Это слишком абстрактно, не хватает конкретики. Однако от фигуры могут наследоваться конкретные формы - круг, квадрат, треугольник и т.д. Вот их экземпляры создать уже можно.
Везде пишут о чисто виртуальных функциях, потому что абстрактным может являться только класс, который содержит как минимум одну чисто виртуальную функцию (т.е. функцию, реализация которой в данном классе не предполагается, а предполагается в классах-наследниках). Приведу пример кода с той же фигурой:

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
#include <iostream>
 
class Shape
{
public:
    virtual double area() const = 0;
};
 
class Square: public Shape
{
public:
    Square(double a = 1): _a(a) { }
 
    virtual double area() const { return _a * _a; }
 
private:
    double _a;
};
 
class Circle: public Shape
{
public:
    Circle(double r = 1): _r(r) { }
 
    virtual double area() const { return 3.14159265358 * _r * _r; }
 
private:
    double _r;
};
 
int main()
{
    Shape *shapes[5];
 
    shapes[0] = new Circle (3);
    shapes[1] = new Square (2);
    shapes[2] = new Square (2.5);
    shapes[3] = new Circle (5);
    shapes[4] = new Circle (10);
 
    for (int i = 0; i < 5; ++i)
        std::cout << shapes[i]->area() << std::endl;
 
    for (int i = 0; i < 5; ++i)
        delete shapes[i];
 
    return 0;
}
Как видите, класс Shape - абстрактный, поскольку там объявлена чисто виртуальная функция area (мы ведь не можем вычислить площадь какой-то абстрактной фигуры...). Зато в классах, которые наследуют от Shape - Circle и Square функция area уже имеет определение. Затем, в главной функции, создаётся массив указателей на Shape (в отличие от экземпляров абстрактного класса, создавать указатели на него мы можем). Затем каждый указатель инициализируется конкретным объектом - кругом или квадратом (поскольку указатель на базовый класс является также указателем на любой производный класс). И затем, в цикле, не задумываясь, в какой ячейке массива какой объект находится, мы просто вызываем для каждого его метод area, а он для каждого объекта выполнит свои действия. Это очень удобно, когда заранее не известно, на какой объект будет указывать очередной указатель (скажем, пользователь сам выбирает, какую фигуру надо создать). Называется это поздним (или динамическим) связыванием.
а если не обьявлять эту "чистую" функцию? т.е. оставить ее виртуальной и все. Разве что то поменяеться в программе? (только наткнулся на эти абстрактные классы..)
т.е. я хочу спросить что что допролнительного дает абстрактный класс относительно обычного с виртуальными методами?
0
silent_1991
Эксперт С++
4997 / 3055 / 149
Регистрация: 11.11.2009
Сообщений: 7,040
Завершенные тесты: 1
29.07.2013, 06:28 #13
zybrzybr, изменится. Если функция не будет чистой виртуальной - объект этого класса можно будет создать. Компилятору, конечно, пофигу на абстракции там всякие, скомпилит и не поперхнётся. Но вот программисту, который про эти абстракции в курсе, ему будет довольно странно видеть в программе объект класса "Форма", умеющий вычислять свою площадь.
3
29.07.2013, 06:28
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.07.2013, 06:28
Привет! Вот еще темы с ответами:

абстрактный класс - C++
стоит ли в абстрактном классе объявлять поля данных? или лучше объявлять только виртуальные функции? с точки зрения правильности как лучше?

Абстрактный класс - C++
Есть базовый абстрактный класс. От него - 2 производных класса. Проблемы: 1) Понимаю, что я не правильно вызываю мои чисто вирт....

Абстрактный класс - C++
#include &lt;iostream.h&gt; #include &lt;conio.h&gt; #include &lt;math.h&gt; #include &lt;windows.h&gt; char bufRus; char* Rus(const char* text) { ...

Абстрактный класс - C++
Друзья, подскажите пожалуйста. Как, вот в этом примере с виртуальной функцией, реализовать уже как абстрактный базовый класс, т.е. с чисто...


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

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

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