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

Неоднозначность при наследовании - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Задача "Гигабашня": минимальное расстояние до этажа со счастливым номером http://www.cyberforum.ru/cpp-beginners/thread1307171.html
Гигабашня — самое высокое и глубокое здание в Киберленде. В ней 17 777 777 777 этажей, пронумерованных от  - 8 888 888 888 до 8 888 888 888. В частности, между этажами  - 1 и 1 есть этаж 0. Тысячи туристов ежедневно приходят сюда, чтобы насладиться чудесным видом. В Киберленде верят, что цифра «8» прносит удачу (именно поэтому в Гигабашне 8 888 888 888 этажей над землей), а целое число...
C++ Лог файл и аргументы командной строки Привет! Осваиваю С++ и нужна помощь, я хочу что бы в командной строке: ввел символ и поменялся след робота, но у меня получается так, что вводишь номер символа по ACSII таблице и только тогда идет смена отрисовки следа, а так не получается. Т.е вводишь номер 63 и идет отрисовка символом вопроса, а нужно просто символ ввести. И еще нужна помощь по логу маршрута робота, нужно получить смену... http://www.cyberforum.ru/cpp-beginners/thread1307155.html
Подскажите сайт, на котором куча задач по написанию программ C++
нужен сайт, на котором куча задач по написанию программ(на паскальке или c++... - не важно) раньше попадался такой, сейчас найти не могу...
С++ дерево представлено в памяти в виде бинарного дерева. Определить максимальное число потомков одного узла C++
дерево представлено в памяти в виде бинарного дерева. Определить максимальное число потомков одного узла в исходном дереве
C++ Как преобразовать int в char http://www.cyberforum.ru/cpp-beginners/thread1307130.html
Подскажите пожалуйста как преобразовать int в char Есть код к примеру: #include<iostream> using namespace std; int main(){ char p; int i=3; p=i;
C++ Что значит этот код? Здравствуйте! #include "stdafx.h" #include <iostream> class T { int x; подробнее

Показать сообщение отдельно
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
3709 / 1984 / 516
Регистрация: 18.10.2014
Сообщений: 3,566
22.11.2014, 00:36     Неоднозначность при наследовании
Цитата Сообщение от lenchis001 Посмотреть сообщение
если наследование виртуальное,
Короткий ответ - потому что этого требуют правила языка.

Длинный ответ:

1. Когда база 'base' является невиртуальной, в вашей иерархии классов есть два корня: левый корень 'base' и правый корень 'base'. Из каждого такого корня вниз растут свои линейки (или даже подыерархии) классов-наследников, в которых как-то по своему перекрывается виртуальная функция 'who'.

В один прекрасный момент эти две линейки (левая и правая) встречаются друг с другом в классе 'result'. Эти две линейки ничего не знают и не должны знать друг о друге. Левая линейка спокойно считает класс 'result' своим наследником, и правая линейка тоже спокойно считает класс 'result' своим наследником.

Пришедшие в класс 'result' две линейки виртуальных функций 'who' тоже сосуществуют независимо, не мешая друг другу. C точки зрения каждой линейки у функции 'who' есть конкретный final overrider не всех уровнях иерархии, в том числе и в 'result'. Левая линейка считает, что для класса 'result' должна работать функция 'left2::who', а правая линейка считает, что для класса 'result' должна работать функция 'right1::who'.

В этом не никакого конфликта. Какая версия 'who' будет работать в каждом конкретном вызове зависит от того, из какой линейки (левой или правой) пришел базовый подобъект 'base', использованный в вызове.

2. Но когда база 'base' становится виртуальной, картина сильно меняется. Теперь в иерархии есть только одна единственная база 'base', один-единственный корень из которого все растет. Из этого единственного корня растут две ветки - левая и правая - которые потом снова встречаются друг с другом в классе 'result'. Пришедшие к класс 'result' линейки перекрытых функций 'who' не являются независимыми - у них общий единственный корень 'base'.

Это уже не две независимых линейки. Это одна единственная общая подыерархия. И рамках этой одной подыерархии класс 'result' не имеет однозначного final overrider для функции 'who'. Это ошибка. Компилятору надо знать конкретный final overrider для функции 'who' в классе 'result'.

===================

Если опуститься на уровень реализации, то можно описать ситуацию так:

1. Когда база 'base' является невиртуальной, в классе 'result' есть два независимых подобъекта 'base', каждый из которых содержит свой указатель на таблицу виртуальных методов (VMT). Левый подобъект 'base' указывает на "левую" VMT, правый - на "правую" VMT. В каждой VMT содержится указатель на свой метод 'who'. Они друг другу никак не мешают.

2. Когда база 'base' является виртуальной, в классе 'result' есть только один подобъект 'base', который разумеется содержит только один указатель на VMT. Так как VMT только одна, компилятор должен знать, что же в нее вписать в качестве указателя на 'who'. Ваш код не дает однозначного ответа на это вопрос, поэтому и возникает ошибка. (Точнее, поэтому спецификация языка говорит, что такая ситуация ошибочна.)
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru