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

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

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

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

09.11.2011, 17:48. Просмотров 2204. Ответов 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: "Предпочитайте композицию наследованию" Хочу уточнить на счет...

52
Сыроежка
Заблокирован
09.11.2011, 21:08 #16
Цитата Сообщение от LosAngeles Посмотреть сообщение
нет, оно не правомерно. Скотт Мейерс в "Эффективном использовании С++. 55 советов" в 32 правиле объясняет почему
Нельзя слепо следовать тому, что написано в книгах!
В данном конкретном примере заранее нельзя сказать, корректно ли такое наследование или нет, так как неизвестно, как определяется прямоугольник. Если для прямоугольника могут быть вызваны все открытые методы четырехугольника, то есть везде, где используется четырехугольник, можно поставить прямоугольник, то такое открытое наследование является корректным.
0
LosAngeles
Заблокирован
10.11.2011, 04:49 #17
Цитата Сообщение от Bers Посмотреть сообщение
Что касается примера Майерса по поводу прямоугольника и квадрата - он искусственный, и высосанный из пальца.
В частности, прямоугольник не обязан содержать разные длины примыкающих сторон.
И нет никакой беды в том, что у прямоугольника все стороны стали равны.
Разумеется в этом нет никакой беды, наверно поэтому мейерс и не обмолвился ни словом об этой проблеме? Не знаю какого мейерса читаешь ты, но в моей книги ничего подобного не написано. В моей написан пример, в результате которого я получаю квадрат с разными сторонами, что делает проблематичным дальнейшее его использование.
Цитата Сообщение от Bers Посмотреть сообщение
Но так же не корректно называть прямоугольник прямоугольником, а потом ассертами запрещать ему иметь одинаковые стороны.
да никто и не запрещал, по крайней мере в 32 правиле издания 2006 года ничего подобного нет!
0
Bers
Заблокирован
10.11.2011, 05:15 #18
Цитата Сообщение от LosAngeles Посмотреть сообщение
Разумеется в этом нет никакой беды, наверно поэтому мейерс и не обмолвился ни словом об этой проблеме?
а ассерт он так просто, для красоты впиндюрил в базовый класс, да?

Добавлено через 16 минут
то есть в пардон, не базовый, а в манипулятор над классом предка
0
LosAngeles
Заблокирован
10.11.2011, 05:36 #19
Не понимаю о чём ты. Я так понял ты намекаешь на то, что какой то ассерт запрещает нам иметь равносторонний прямоугольник? Нет не запрещает, в чём проблема то? Там есть ассерт который запрещает иметь разносторонний квадрат, что вполне логично и правомерно. Собственно на это и обращается внимание
0
Bers
Заблокирован
10.11.2011, 06:13 #20
Цитата Сообщение от LosAngeles Посмотреть сообщение
Не понимаю о чём ты. Я так понял ты намекаешь на то, что какой то ассерт запрещает нам иметь равносторонний прямоугольник? Нет не запрещает, в чём проблема то? Там есть ассерт который запрещает иметь разносторонний квадрат, что вполне логично и правомерно. Собственно на это и обращается внимание
Ну мне что, сюда спокипастить эту идиотскую функцию?

void makebigger(Rectange& r); //что за идиотский ассерт запихал в неё Маерс, и что он имел ввиду? Обрати внимание, в качестве аргумента принимается прямоугольник, а не квадрат. Что за ДИБИЛИЗМ? Вешать ассерт, запрещающий прямоугольнику иметь разные примыкающие стороны?

тело функции:
C++
1
2
3
4
5
6
void makeBigger(rectange& r)
{
int old = r.height();
r.setWidth( r.width()+10);
assert( r.height() == old )
}
Теперь объясните мне пожалуйста, с точки зрения здравого смысла, зачем нужен такой дибильный ассерт, и какое отношение это имеет к наследованию?

Добавлено через 24 минуты
ой... не разные, а наоборот обязательное одинаковые. Тьху ты блин...
0
PointsEqual
ниначмуроФ
836 / 520 / 33
Регистрация: 12.10.2009
Сообщений: 1,915
10.11.2011, 08:29 #21
конкретно по вопросу ramarren14

При объявлении функции виртуальной,
компилятор выбирает функцию, удовлетворяющему тому, что занесено в указатель, а не типу указателя.

То есть единственный плюс
нет не единтственный
0
Bers
Заблокирован
10.11.2011, 08:44 #22
Цитата Сообщение от PointsEqual Посмотреть сообщение
При объявлении функции виртуальной,
компилятор выбирает функцию, удовлетворяющему тому, что занесено в указатель, а не типу указателя.
забей, и не парься
http://www.devdoc.ru/index.php/content/view/virtual_base.htm
0
ValeryLaptev
Эксперт С++
1041 / 820 / 48
Регистрация: 30.04.2011
Сообщений: 1,659
10.11.2011, 08:54 #23
Цитата Сообщение от Bers Посмотреть сообщение
можно.
Лучше так не делать...
По поводу наследования и виртуальности.
При наследовании (в С++ - только при открытом) работает принцип подстановки: на место объекта (указателя, ссылки) можно подставить объект производного класса. Обратно - нельзя.
Наболее понятный пример: часы-будильник.
Часы - базовый класс, будильник - наследник. Будильник является часами, но часы - не будильник.

По поводу виртуальности - она без наследования совершенно бесполезна.
А при наследовании полезна, например вот здесь:
C++
1
2
3
4
5
6
7
class Base { ... public:
void f() { cout << "Base"; }
void Call() { f(); }
};
class Derived: public Base
{ ... public: void f() { cout << "Derived"; }
};
Тут мы переопределяем в наследнике вызываемую функцию, а вызывающую наследуем.
Однако!
C++
1
Derived A; A.Call();
вызывается базовая функция f().
А если сделать ее виртуальной, то вызывается своя для каждого типа.
0
Bers
Заблокирован
10.11.2011, 09:00 #24
это все здорово, только у нас есть конкретная задача - отнаследовать прямоугольник от четырёх угольника. В чем проблема?

Добавлено через 1 минуту
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Derived A; A.Call();
вызовется метод, пренадлежащий Derived
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1305 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
10.11.2011, 09:05 #25
Цитата Сообщение от Bers Посмотреть сообщение
вызовется метод, пренадлежащий Derived
Функция Call определена в Base. f не виртуальная, поэтому полиморфного вызова не будет.
0
ValeryLaptev
Эксперт С++
1041 / 820 / 48
Регистрация: 30.04.2011
Сообщений: 1,659
10.11.2011, 09:16 #26
Цитата Сообщение от Bers Посмотреть сообщение
вызовется метод, пренадлежащий Derived
Нет. Без виртуальности вызовется базовый...
0
LosAngeles
Заблокирован
10.11.2011, 10:03 #27
Цитата Сообщение от Bers Посмотреть сообщение
void makebigger(Rectange& r); //что за идиотский ассерт запихал в неё Маерс, и что он имел ввиду? Обрати внимание, в качестве аргумента принимается прямоугольник, а не квадрат. Что за ДИБИЛИЗМ? Вешать ассерт, запрещающий прямоугольнику иметь разные примыкающие стороны?
Этот ассерт не запрещает иметь прямоугольнику одинаковые примыкающее стороны! Не надо сочинять небылицы. Выражение внутри этого ассерта всегда равно Тру, внезависимости от того равны смежные стороны, или не равны. В выражении фигурирует только высота прямоугольника на момент начала работы функции и высота по завершению работы функции, ширины вобще там нет, она ни с чем не сравнивается. Равна она высоте или нет - вобще пофигу! Этот ассерт не запрещает иметь прямоугольнику однаковые прилегающие стороны как ты выразился... Смысл этого ассерта в том чтобы показать, что в прямоугольнике одна сторона может изменяться независимо от другой и при открытом наследовании данное свойство передастся и квадрату, что недопустимо!

Нет в примере Мейерса ничего дебильного, он же не виноват, что ты отрываешь книгу и видишь в ней фигу, а потом ещё и копируешь и тоже видишь при этом фигу. У меня уже слов нету, ты уже трижды пытался меня убедить в том, что этот ассерт запрещает иметь одинаковые смежные стороны прямоугольнику, что просто не соответсвует действительности! Или ты думаешь что если повторить ложь много раз, то она станет правдой или я в неё поверю? Нет. Если это какая то шутка, то я её не понял
0
bob2005
0 / 0 / 0
Регистрация: 10.11.2011
Сообщений: 10
10.11.2011, 10:23 #28
У мя аж глаз задергался, так что все таки вызывает A.Call
0
ValeryLaptev
Эксперт С++
1041 / 820 / 48
Регистрация: 30.04.2011
Сообщений: 1,659
10.11.2011, 12:23 #29
Цитата Сообщение от bob2005 Посмотреть сообщение
У мя аж глаз задергался, так что все таки вызывает A.Call
Без виртуальности f() всегда вызывается функция базового класса.
С виртуальностью f() вызывается функция по типу объекта A.
Аналогично с указателями:
C++
1
2
3
4
Base *p;
Derived A;
p = &A;
p->Call();
При виртуальности вызовется f() наследника, без виртуальности - f() базовая
0
bob2005
0 / 0 / 0
Регистрация: 10.11.2011
Сообщений: 10
10.11.2011, 14:25 #30
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Без виртуальности f() всегда вызывается функция базового класса.
С виртуальностью f() вызывается функция по типу объекта A.
Аналогично с указателями:
Код C++1
2
3
4 Base *p;
Derived A;
p = &A;
p->Call();
При виртуальности вызовется f() наследника, без виртуальности - f() базовая
Объясните нубу зачем делать указатель на base, а затем засовывать в него адрес Derived.
0
10.11.2011, 14:25
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.11.2011, 14:25
Привет! Вот еще темы с ответами:

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

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

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

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


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

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

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