Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Классы, Наследование классов 
:(
    Опции темы
bel_nikita
Дата 5.11.2003, 10:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



maxim1000
Цитата
но ведь класс cB включает методы класс cA, значит, при подключении cB в класс cC в нем и так будут методы обоих классов


это так, но сА иммет виртуальный метод. class cC - не может изменить метод cB. У него должен быть свой метод на сА.



--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
Vyacheslav
Дата 5.11.2003, 17:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 9
Всего: 59



Цитата(bel_nikita @ 4.11.2003, 13:20)
А вот так:

class cE: public/private cB, public/private cA {...};

не работает!
Почему?sad.gif

Ну а кто тебе мешает использовать промежуточный класс
Код

class cA {...}; //здесь есть функционал

class cB: public  cA {...}; //здесь тоже есть

class cD: public cA {}; // промежуточный класс - здесь функционал не изменен

class cE: public cB, public cD {...};


Что же касается вопроса: "Почему?sad.gif", то возможно это несоответствие стандарту. По крайней мере стандарт это не запрещает (во всяком случае я так понял 10.1 параграф 3)
Цитата

The сlass can be not specified as direct base class of the derived class more then once. [Note: class can be an indirect base class more then once and  can be direct and indirect base class . ...


"Класс не может быть специфирован как прямой базовый класс производного класса более чем одинраз. Примечание: класс может быть косвенным базовым классом более одного раза и может быть прямым и косвенным базовым классом "





--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Vyacheslav
Дата 5.11.2003, 17:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 9
Всего: 59



Цитата(Ars @ 4.11.2003, 12:28)
Значит, с точки зрения компиллятора это принципам ООП всетаки противоречит.

Если каждый раз оглядываться на конкретную реализацию компилятора, то от стандарта ничего не останется.
Цитата(Ars)

Для него возникает неразрешимая неоднозначность  sad.gif

Интересно, откуда она возмется? По стандарту при таком наследовании создаются две копии TBase
А этот код действительно не пройдет.
Цитата(Ars)

Код
{
TIzvrat *Izvrat=new TIzvrat();
int I=Izvrat->Value;
// Какое значение должна принять переменная I confused.gif
}


Тут надо обязательно уточнять:значение Value которой копии TBase нам требуется. Поэтому нужно так
Код

TIzvrat *Izvrat=new TIzvrat();
int I=Izvrat->TBase::Value;
int J = Izvrat->TDerived::Value;



--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Ars
Дата 5.11.2003, 18:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 325
Регистрация: 28.8.2003
Где: Московская обл.

Репутация: 2
Всего: 2



Код
int I=Izvrat->TBase::Value;

Вот-вот. Как укажешь TBase, там-то он и загнется от невозможности решить, из какой же копии брать значение smile.gif


--------------------
Есть многое на свете, друг Горацио,
С чем очень долго можно прое..!
PM MAIL   Вверх
mr.DUDA
Дата 5.11.2003, 20:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 25
Всего: 232



Народ, мне вот интересно, а почему никто не вспомнил про виртуальные базовые классы ?

Код
class  X {...};
class  Y : public virtual X {...};
class  Z : public virtual X {...};
class  D : public Y, public Z  {...};


При обычном наследовании (без virtual) схема такова:
X ----> Y ----> D <---- Z <---- X

При виртуальном - схема наследования будет такова:

D<----- Y <---- X
+<----- Z <---- +


ИМХО, это именно то, что надо спросившему.

© Подбельский В.В. "Язык Си++", 1999

Это сообщение отредактировал(а) mr.DUDA - 5.11.2003, 20:38


--------------------
user posted image
PM MAIL WWW   Вверх
RAN
Дата 5.11.2003, 22:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Экс. модератор
Сообщений: 709
Регистрация: 14.3.2003
Где: Щёлково Моск.обл.

Репутация: 5
Всего: 6



Не вспомнили, потому что вопрос не про виртуальное наследование.

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

class A {
public:
virtual void f();
};

class B : virtual public A {
public:
virtual void f();
};

class C : virtual public B, virtual public A {

};

Во-первых, не понятно зачем вообще наследовать С от 2 классов. Это я объясняю тем, что разработчики так "подстраховались" smile.gif . Схема намного сложнее и запутанее, а я просто разрез привёл.
Во-вторых, при компиляции в VC выдаётся предупреждение, что функции A::f() не доступна.
PM MAIL ICQ   Вверх
Vyacheslav
Дата 6.11.2003, 10:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 9
Всего: 59



Цитата(Ars @ 5.11.2003, 18:46)
Код
int I=Izvrat->TBase::Value;

Вот-вот. Как укажешь TBase, там-то он и загнется от невозможности решить, из какой же копии брать значение smile.gif

Я так понимаю, Вы уже со стандартом спорите , а не со мной. И кто интересно загнется? Компилятор? Проверить очень просто. Возьмите компилятор, который поддерживает стандарт, например VC7++ и проверьте, загнется или не загнется
А компилятор четко понимает, что

TIzvtar::TBase::Value это совсем другое, чем
TIzvrat::TDerived::TBase::Value


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Ars
Дата 6.11.2003, 11:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 325
Регистрация: 28.8.2003
Где: Московская обл.

Репутация: 2
Всего: 2



Цитата
Я так понимаю, Вы уже со стандартом спорите , а не со мной. И кто интересно загнется? Компилятор? Проверить очень просто. Возьмите компилятор, который поддерживает стандарт, например VC7++ и проверьте, загнется или не загнется
А компилятор четко понимает, что

TIzvtar::TBase::Value это совсем другое, чем
TIzvrat::TDerived::TBase::Value


Можно и на ты smile.gif
Я все-таки иногда проверяю то, что пишу в форум и это как раз один из таких случаев wink.gif
А результаты таковы.
Компилим вышеприведенный код под CBuilder6:
Цитата
Build
  [C++ Warning] Unit1.h(37): W8024 Base class 'TBase' is also a base class of 'TDerived'
  [C++ Error] Unit1.cpp(33): E2312 'TBase' is not an unambiguous base class of 'TIzvrat'
  [C++ Warning] Unit1.cpp(34): W8004 'Izvrat' is assigned a value that is never used

Под Visual C++ 6.0:
Цитата
Compiling...
Test.cpp
Test.cpp(20) : error C2584: 'TIzvrat' : direct base 'TBase' is inaccessible; already a base of 'TDerived'
        Test.cpp(9) : see declaration of 'TBase'

Т.е. int I=Izvrat->TBase::Value; в двух ведущих компиляторах не проходит.
Я не хочу сказать, что это все противоречит принципам ООП, а только то, что это реализовать не получится, да и не нужно, кроме случаев академического программирования


--------------------
Есть многое на свете, друг Горацио,
С чем очень долго можно прое..!
PM MAIL   Вверх
Vyacheslav
Дата 6.11.2003, 12:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 9
Всего: 59



К сожалению компиляторы С++Builder 6 и Visual C++ 6.0 в данном аспекте не соответсвуют стандарту.
Кстати они далеко не ведущие. Я же указал, надо использовать Visual C++ 7.0. Что касается С++Builder 6, я уже пару дней назад отправил Borland'у bug report за номером 6367.
Код

struct A
{
  int val;
  A(){val = 1;}
};

struct B : public A
{
   B():A(){val = 2;}
};

struct C: public B, public A
{
   // C() :B(),A(){}    [C++ Error]  Unit1.cpp(17): E2312 'A' is not an unambiguous base class of 'C'
       C(){};
};

int main(int argc, char* argv[])
{

C c;
// int i =  c.A::val;   [C++ Error] Unit1.cpp(29): E2316 'A' is not a member of 'C'
// int i =  c.val;       [C++ Error] Unit1.cpp(29): E2014 Member is ambiguous: 'A::val' and 'A::val'
int j =  c.B::val;
return 0;
}



Что касается чисто академического вопроса, то практически он спокойно решается
Код

class TBase
{
public:
int Value;
TBase(){Value=1;};
};
class TBase1 : public TBase{};

class TDerived : public TBase
{
public:
TDerived(){Value=2;};
};
class TIzvrat : public TBase1, public TDerived
{
public:
TIzvrat(){};
};
//---------------------------------------------------------------------------

#pragma argsused
int main(int argc, char* argv[])
{

TIzvrat Izvrat;
int i =  Izvrat.TBase1::Value;    //i == 1
int j =  Izvrat.TDerived::Value; // j== 2
 return 0;
}

При этом фактически отличий от первого варианта нет


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Ars
Дата 6.11.2003, 12:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 325
Регистрация: 28.8.2003
Где: Московская обл.

Репутация: 2
Всего: 2



Ну, сдаюсь, сдаюсь. smile.gif


--------------------
Есть многое на свете, друг Горацио,
С чем очень долго можно прое..!
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0519 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.