Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 284, средняя оценка - 4.76
BTR
 Аватар для BTR
8 / 8 / 1
Регистрация: 01.11.2010
Сообщений: 157
12.01.2011, 20:42     абстрактный класс #1
Всем привет, снова я, только уже с новым вопросом, а что такое абстрактный класс. Читаю книгу, не могу врубиться, рассказывается про какие-то чисто виртуальные методы, можете мне рассказать чем отличается абстрактный класс от простого и привести пример. Заранее спасибо

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

Абстрактный класс C++
Написать обработчик исключений ситуации при преобразовании указателя на класс B до указателя на абстрактный класс А ... C++
C++ Абстрактный класс
C++ Создать класс - данные - абстрактный базовый класс. Создать производные классы
C++ Создать абстрактный базовый класс Тройка чисел с виртуальными методами увеличения на 1. Создать производный класс Время со своими функциями
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 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, а он для каждого объекта выполнит свои действия. Это очень удобно, когда заранее не известно, на какой объект будет указывать очередной указатель (скажем, пользователь сам выбирает, какую фигуру надо создать). Называется это поздним (или динамическим) связыванием.
BTR
 Аватар для BTR
8 / 8 / 1
Регистрация: 01.11.2010
Сообщений: 157
12.01.2011, 21:16  [ТС]     абстрактный класс #3
что то на счет объявления объекта в вашем коде не понял, раз класс Shape абстрактный, то как вы его значения даете объекту, попросту говоря как из него вы делаете объект, растолкуйте пожалуйста, заранее благодарен
sandye51
программист С++
 Аватар для sandye51
677 / 579 / 39
Регистрация: 19.12.2010
Сообщений: 2,016
12.01.2011, 21:22     абстрактный класс #4
BTR, проще говоря, указатель на базовый класс могут указывать на объекты любых отнаследованных от него классов;
BTR
 Аватар для BTR
8 / 8 / 1
Регистрация: 01.11.2010
Сообщений: 157
12.01.2011, 21:27  [ТС]     абстрактный класс #5
Цитата Сообщение от sandye51 Посмотреть сообщение
BTR, проще говоря, указатель на базовый класс могут указывать на объекты любых отнаследованных от него классов;
я немного не понял что вы сказали, пожалуйста перефразируйте предложение, если Вам не сложно, благодарю! =)

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

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

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

Добавлено через 1 минуту
BTR, да, всё верно)))
BTR
 Аватар для BTR
8 / 8 / 1
Регистрация: 01.11.2010
Сообщений: 157
12.01.2011, 21:44  [ТС]     абстрактный класс #9
спасибо, если кто-то тут изучает PHP и у него ничего не получается, обращайтесь, я помогу, всем спасибо
RASHFor
6 / 6 / 0
Регистрация: 12.02.2012
Сообщений: 224
18.03.2013, 15:16     абстрактный класс #10
Извините,а что означает строчка
C++
1
 Square(double a = 1): _a(a) { }
Конструктор ?
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
18.03.2013, 15:45     абстрактный класс #11
RASHFor, да. Конструктор с одним параметром по умолчанию (может быть вызван с одним параметром типа double или типа, который компилятор может автоматически привести к double, или же без параметров, что будет эквивалентно вызову его с одним параметром - единицей), который посредством списка инициализации инициализирует поле _a значением параметра конструктора a.
zybrzybr
 Аватар для 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, а он для каждого объекта выполнит свои действия. Это очень удобно, когда заранее не известно, на какой объект будет указывать очередной указатель (скажем, пользователь сам выбирает, какую фигуру надо создать). Называется это поздним (или динамическим) связыванием.
а если не обьявлять эту "чистую" функцию? т.е. оставить ее виртуальной и все. Разве что то поменяеться в программе? (только наткнулся на эти абстрактные классы..)
т.е. я хочу спросить что что допролнительного дает абстрактный класс относительно обычного с виртуальными методами?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.07.2013, 06:28     абстрактный класс
Еще ссылки по теме:

C++ Абстрактный класс
C++ абстрактный класс
Абстрактный класс/Класс интерфейс C++

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

Или воспользуйтесь поиском по форуму:
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
29.07.2013, 06:28     абстрактный класс #13
zybrzybr, изменится. Если функция не будет чистой виртуальной - объект этого класса можно будет создать. Компилятору, конечно, пофигу на абстракции там всякие, скомпилит и не поперхнётся. Но вот программисту, который про эти абстракции в курсе, ему будет довольно странно видеть в программе объект класса "Форма", умеющий вычислять свою площадь.
Yandex
Объявления
29.07.2013, 06:28     абстрактный класс
Ответ Создать тему
Опции темы

Текущее время: 14:20. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru