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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 17, средняя оценка - 4.82
ramarren14
2 / 2 / 0
Регистрация: 14.07.2011
Сообщений: 49
#1

Вопрос по наследованию - C++

09.11.2011, 17:48. Просмотров 2171. Ответов 52
Метки нет (Все метки)

Уже неоднократно перечитывал главы про наследования и все равно до конца не разобрался.
Вот например у нас есть класс Четырехугольник, и мы создаем класс Прямоугольник.
И в том и в другом классе есть функции Площадь и если у них будет одинаковая сигнатура, то вызовется функция того класса, объект которого мы создали. Если же сигнатуры совпадать не будут, то нужно явно указать с помощью оператора ::.
Если мы сделаем функцию площади виртуальной, то при одинаковых сигнатурах вызовется функция своего класса. То же в случае разных сигнатур. То есть единственный плюс объявления функций виртуальными, это то что если мы создадим указатель на объект базового класса, он сможет указывать и на объект производного класса?
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.11.2011, 17:48
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Вопрос по наследованию (C++):

Вопрос по наследованию - C++
Вопрос насчёт передачи аргументов в конструктор базового класса(создания временного объекта), а именно почему у меня это не выходит и где у...

Вопросы по наследованию - C++
Вопрос ещё по конструкторам Допустим есть система классов class A { public: A() {} }; class B: public A {

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

Задача по наследованию в C++, нужно реализовать некоторые моменты - C++
Написать программу с объектами и реализовать наследование. Ситуация: Klimat (базовый объект), Derevo (выводной объект). a. Klimat:...

Задача по наследованию. Не понимаю некоторые моменты в формулировке задания - C++
Здравствуйте! Вот есть задание: Описать базовый класс СТРОКА Обязательные поля класса: # Указатель на char - хранит адрес...

"Предпочитайте композицию наследованию" - C++
Привет. В книге "Стандарты программирования на С++" есть совет 34: "Предпочитайте композицию наследованию" Хочу уточнить на счет...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Chelioss
180 / 180 / 4
Регистрация: 08.01.2011
Сообщений: 1,133
09.11.2011, 17:56 #2
Какая еще сигнатура?
Что-то мне подсказывает, что вы не внимательно читали, раз предположили такое
Цитата Сообщение от ramarren14 Посмотреть сообщение
он сможет указывать и на объект производного класса?
0
bretba
63 / 58 / 5
Регистрация: 24.07.2011
Сообщений: 343
09.11.2011, 18:00 #3
зарезервированное слово virtual у члена класса показывает, что этот член может иметь разную версию в наследованных классах(то есть разное описание).

Виртуальные функции очень удобно использовать в играх.К примеру есть базовый класс-"оружие",где есть виртуальная функция "пули".От этого класса наследуются такие классы как-"автомат","пистолет" и тд.У каждого оружия есть своя специфика стрельбы-у автомата постоянными,у пистолета-одиночными и тд.И вот чтобы,для каждого не писать отдельных функций,можно использовать ту виртуальную функцию "пули".И для каждого класса описание этой функции будет свое.Удобно?Удобно))
0
ramarren14
2 / 2 / 0
Регистрация: 14.07.2011
Сообщений: 49
09.11.2011, 18:03  [ТС] #4
Джесс Либерти "Освой С++ за 21 день";
cтр 324: "Полиформизм в С++ развит настолько, что допускается присвоение указателям на базовый класс адресов объектов производных классов как это делается в следующем примере"
Mammal * Ptr=new Dog;
0
Chelioss
180 / 180 / 4
Регистрация: 08.01.2011
Сообщений: 1,133
09.11.2011, 18:06 #5
Цитата Сообщение от ramarren14 Посмотреть сообщение
cтр 324: "Полиформизм в С++ развит настолько, что допускается присвоение указателям на базовый класс адресов объектов производных классов как это делается в следующем примере"
Mammal * Ptr=new Dog;
Где тут слово vitual?
0
LosAngeles
Заблокирован
09.11.2011, 18:07 #6
неудачный пример, нельзя наследовать прямоугольник от четырёхугольника
0
Van111
кодер с++
209 / 188 / 4
Регистрация: 03.08.2011
Сообщений: 2,597
Записей в блоге: 12
09.11.2011, 18:10 #7
C++
1
2
3
4
5
6
7
8
Shape *ShapeArray[3] ;
 
ShapeArray[0] = new Circl ;
ShapeArray[1] = new Rectang;
ShapeArray[2] = new Square;
 
for(int i = 0; i < 3; i++)
ShapeArray[i]->Draw() ;
все эти три класса производные класса snape в котором функция Draw объявлена ключевым словом virtual
в каждом из этих трёх классов ясть своя функция Draw
в данном случае программа сама разбирает с какой фигурой мы имеем дело
0
Chelioss
180 / 180 / 4
Регистрация: 08.01.2011
Сообщений: 1,133
09.11.2011, 18:15 #8
Вот пример.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
 
class Base 
{
public:
    void fun() { std::cout << "class Base\n"; };
};
 
class Derived: public Base
{
    void fun() { std::cout << "class Derived\n"; };
};
 
int main()
{
    Base *basePtr = new Derived;
    basePtr->fun(); // class Base
    system( "pause" );
    return 0;
}
Помечу вызывается функция класса Base? Потому что тип указателя - Base. Логично? Логично и это так.
А что если мы хотим вызвать функцию класса Derived?
Тогда добавляем спецификатор virtual для функции fun() в классе Base.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
 
class Base 
{
public:
    virtual void fun() { std::cout << "class Base\n"; };
};
 
class Derived: public Base
{
    void fun() { std::cout << "class Derived\n"; };
};
 
int main()
{
    Base *basePtr = new Derived;
    basePtr->fun(); // class Derived
    system( "pause" );
    return 0;
}
Тут надо заметить, что если функция fun класса Base является виртуальной, то по умолчанию функция fun класса Derived тоже станет виртуальной( при наследовании, конечно ), а поэтому для наглядности можно написать так( это тоже самое, что и выше написано):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
 
class Base 
{
public:
    virtual void fun() { std::cout << "class Base\n"; };
};
 
class Derived: public Base
{
    virtual void fun() { std::cout << "class Derived\n"; };
};
 
int main()
{
    Base *basePtr = new Derived;
    basePtr->fun(); // class Derived
    system( "pause" );
    return 0;
}
0
Bers
Заблокирован
09.11.2011, 18:51 #9
Цитата Сообщение от LosAngeles Посмотреть сообщение
неудачный пример, нельзя наследовать прямоугольник от четырёхугольника
можно.
0
LosAngeles
Заблокирован
09.11.2011, 18:54 #10
Цитата Сообщение от Bers Посмотреть сообщение
можно.
разумеется нет.
0
Chelioss
180 / 180 / 4
Регистрация: 08.01.2011
Сообщений: 1,133
09.11.2011, 18:54 #11
Цитата Сообщение от LosAngeles Посмотреть сообщение
разумеется нет.
Прямоугольник является четырехугольником. Разве нет?
0
Bers
Заблокирован
09.11.2011, 19:00 #12
Цитата Сообщение от LosAngeles Посмотреть сообщение
разумеется нет.
аргументируйте

Добавлено через 30 секунд
Цитата Сообщение от Chelioss Посмотреть сообщение
Прямоугольник является четырехугольником. Разве нет?
да. Именно поэтому, наследование правомерно.

Прямоугольник есть частный случай четырех угольника.
0
LosAngeles
Заблокирован
09.11.2011, 19:15 #13
нет, оно не правомерно. Скотт Мейерс в "Эффективном использовании С++. 55 советов" в 32 правиле объясняет почему
0
Bers
Заблокирован
09.11.2011, 19:41 #14
Цитата Сообщение от LosAngeles Посмотреть сообщение
нет, оно не правомерно. Скотт Мейерс в "Эффективном использовании С++. 55 советов" в 32 правиле объясняет почему
Специально открыл и прочитал. Ну так вот, по мнению Маерса, при открытом наследовании, потомок является частным случаем предка.

Это означает, что все функции, которые умеют работать с предком, должны сработать и с потомком.

И наоборот: те функции, которые специализированы для потомка - не сработают с предком.


Ну так вот, в нашем случае любые операции, над четырех угольником сработают и над прямоугольником.

А вот некоторые операции над прямоугольником, могут не сработать с четырех угольником.

Что касается примера Майерса по поводу прямоугольника и квадрата - он искусственный, и высосанный из пальца.

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

Если нужно обеспечить гарантию того, что в прямоугольнике длины прилегающих сторон должны быть обязательно разными - вот это уже надо делать отдельную сущность. Потмоу что такая фигура уже не "прямоугольник". Это что-то вроде "разностороннего прямоугольника", у которого ширина и высота обязательно должны быть разными.

То есть, понятно, что квадрат от "разностороннего прямоугольника" наследовать не корректно.

Но так же не корректно называть прямоугольник прямоугольником, а потом ассертами запрещать ему иметь одинаковые стороны.

Поэтому, пример Майерса не удачный. Имхо.
1
bretba
09.11.2011, 19:43     Вопрос по наследованию
  #15

Не по теме:

жесть вы тут диалог развели))

0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.11.2011, 19:43
Привет! Вот еще темы с ответами:

Написать простейшую программу по "перегрузке" и "наследованию" - C++
написать простейшую программу на СИ++ по &quot;перегрузке&quot; и &quot;наследованию&quot;. заранее спасибо!

Вопрос по массивав, "институтский" вопрос. - C++
Готовлюсь к летней сессии по программированию. С++ Есть такая вот задачка (привожу как есть) В документации подобного не...

Вопрос по наследованию - C#
Вывод Hello СHild Hello Base Что сделать чтобы Base не выводило при подобном вызове? using System; namespace...

вопрос по наследованию - PHP ООП
начал изучать ООП в РНР. нужно уточнение. имеется класс статей Aticle и дочерний класс NewsArticle, они отличаются тем что у второго...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
09.11.2011, 19:43
Ответ Создать тему
Опции темы

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