Re[9]: множественное наследование и полиморфизм
От: Аноним  
Дата: 22.09.04 11:04
Оценка:
Чего не знаю — того не знаю.
Эта фигня не компилируется в BC++3.0 (только не смейтесь. Это то, что оказалось под рукой.) Так что счет — 2 : 1 — не в пользу VC7
Re[10]: множественное наследование и полиморфизм
От: Shhady Россия  
Дата: 22.09.04 11:06
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Чего не знаю — того не знаю.

А>Эта фигня не компилируется в BC++3.0 (только не смейтесь. Это то, что оказалось под рукой.) Так что счет — 2 : 1 — не в пользу VC7

в comeau то же
"Man feed machine
Machine feed man"
Peter Gabriel — OVO — The Tower That Ate People
Re[11]: множественное наследование и полиморфизм
От: Аноним  
Дата: 22.09.04 11:10
Оценка:
Еще раз посылаю всех почитать Герба Саттера (Задача о разделении сиамских близнецов),
а про первоначальный вариант забудьте.
Re: множественное наследование и полиморфизм
От: poilk  
Дата: 22.09.04 11:13
Оценка: 2 (1)
Здравствуйте, machine1, Вы писали:

M>Привет,


M>незнаю как сделать, хотелось что-то типа этого:



M>
M>class A
M>{
M>public:
M>   virtual void f() = 0;
M>};

M>class B
M>{
M>public:
M>   virtual void f() = 0;
M>};

M>class AB : public A, public B
M>{
M>public:
M>   void A::f() {/*тут реализация*/}
M>   void B::f() {/*тут реализация*/}
M>}
M>


Смысл виртуального множественного наследования в том, чтобы вызвать нужную функцию в зависимости от типа:
class A
{
public:
   void f(){ cout << "A::f()" << endl;}
};

class B
{
public:
   void f(){ cout << "B::f()" << endl;}
};

class AB : virtual public A, virtual public B
{
};


int main(int argc, char* argv[])
{
    A *a = new AB;
    B *b = new AB;
    
    a->f();
    b->f();
  return 0;
}


А смысл чисто виртуальной функции в том, чтобы возложить реализацию на производный класс:
class A
{
public:
   virtual void f() = 0;
};

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

class AB : virtual public A, virtual public B
{
public:
   void f() {
       cout << "f()" << endl;
   }
};


int main(int argc, char* argv[])
{
    AB *ab = new AB;
    
    ab->f();
  return 0;
}


Код в вопросе можно поправить так:
class A
{
public:
   virtual void fA() = 0;
};

class B
{
public:
   virtual void fB() = 0;
};

class AB : public A, public B
{
public:
   void fA() {
       cout << "A::fA()";
   }
   void fB() {
       cout << "B::fB()";
   }
};


Или так:
class A
{
public:
   void f(){ cout << "A::f()" << endl;}
};

class B
{
public:
   void f(){ cout << "B::f()" << endl;}
};

class AB : virtual public A, virtual public B
{
public:
   void f() {
       cout << "AB::f()" << endl;
   }
};

int main(){
    AB *ab = new AB;
    ab->f();
    ab->A::f();
    ab->B::f();
}


Кстати gnu-шный компиллятор ругается на этот код по-другому:

error: cannot declare member function `A::f' within `AB'
error: cannot declare member function `B::f' within `AB'

... << RSDN@Home 1.1.4 beta 3 rev. 0>>
Re[12]: множественное наследование и полиморфизм
От: Аноним  
Дата: 22.09.04 11:18
Оценка:
Я вот не пойду читать Саттера, хоть ты меня и призвал. А тебя призову почитать дизайн и эволюция С++, чтоб ты не думал, будто это Саттер изобрел
Re[13]: множественное наследование и полиморфизм
От: Аноним  
Дата: 22.09.04 11:24
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Я вот не пойду читать Саттера, хоть ты меня и призвал. А тебя призову почитать дизайн и эволюция С++, чтоб ты не думал, будто это Саттер изобрел


Я не говорю, что это он изобрел. Я ссылаюсь на то, где об этом прочитал.
Если Страуструп об этом что-то написал — очень хорошо. Можно посмотреть и там.
Re[2]: множественное наследование и полиморфизм
От: Аноним  
Дата: 22.09.04 11:39
Оценка:
Здравствуйте, poilk, Вы писали:

P>Здравствуйте, machine1, Вы писали:


M>>Привет,


M>>незнаю как сделать, хотелось что-то типа этого:



M>>
M>>class A
M>>{
M>>public:
M>>   virtual void f() = 0;
M>>};

M>>class B
M>>{
M>>public:
M>>   virtual void f() = 0;
M>>};

M>>class AB : public A, public B
M>>{
M>>public:
M>>   void A::f() {/*тут реализация*/}
M>>   void B::f() {/*тут реализация*/}
M>>}
M>>


P>Смысл виртуального множественного наследования в том, чтобы вызвать нужную функцию в зависимости от типа:

P>
P>class A
P>{
P>public:
P>   void f(){ cout << "A::f()" << endl;}
P>};

P>class B
P>{
P>public:
P>   void f(){ cout << "B::f()" << endl;}
P>};

P>class AB : virtual public A, virtual public B
P>{
P>};


P>int main(int argc, char* argv[])
P>{
P>    A *a = new AB;
P>    B *b = new AB;
    
    a->>f();
    b->>f();
P>  return 0;
P>}
P>


P>А смысл чисто виртуальной функции в том, чтобы возложить реализацию на производный класс:

P>
P>class A
P>{
P>public:
P>   virtual void f() = 0;
P>};

P>class B
P>{
P>public:
P>   virtual void f() = 0;
P>};

P>class AB : virtual public A, virtual public B
P>{
P>public:
P>   void f() {
P>       cout << "f()" << endl;
P>   }
P>};


P>int main(int argc, char* argv[])
P>{
P>    AB *ab = new AB;
    
    ab->>f();
P>  return 0;
P>}
P>


P>Код в вопросе можно поправить так:

P>
P>class A
P>{
P>public:
P>   virtual void fA() = 0;
P>};

P>class B
P>{
P>public:
P>   virtual void fB() = 0;
P>};

P>class AB : public A, public B
P>{
P>public:
P>   void fA() {
P>       cout << "A::fA()";
P>   }
P>   void fB() {
P>       cout << "B::fB()";
P>   }
P>};
P>


P>Или так:

P>
P>class A
P>{
P>public:
P>   void f(){ cout << "A::f()" << endl;}
P>};

P>class B
P>{
P>public:
P>   void f(){ cout << "B::f()" << endl;}
P>};

P>class AB : virtual public A, virtual public B
P>{
P>public:
P>   void f() {
P>       cout << "AB::f()" << endl;
P>   }
P>};

P>int main(){
P>    AB *ab = new AB;
    ab->>f();
    ab->>A::f();
    ab->>B::f();
P>}
P>


P>Кстати gnu-шный компиллятор ругается на этот код по-другому:

P>

P>error: cannot declare member function `A::f' within `AB'
P>error: cannot declare member function `B::f' within `AB'

Re[2]: множественное наследование и полиморфизм
От: Аноним  
Дата: 22.09.04 11:40
Оценка: 2 (1)
Да простит меня Аноним, но я опять буду ссылаться на Саттера.


P>Смысл виртуального множественного наследования в том, чтобы вызвать нужную функцию в зависимости от типа:


Нет, не так.
Виртуальное наследование предотвращает создание двух экземпларов базового класса.

class Base {};

class DerA : public Base {};
class DerB : public Base {};

class DerDer1 : public DerA, public DerB {}; // Данные класса Base бублируюутся.
class DerDer2 : virtual public DerA, virtual public DerB {}; // А тут вроде нет.


А все варианты, представленные ниже по моему не соответствуют начальной задумке


P>
P>class A
P>{
P>public:
P>   void f(){ cout << "A::f()" << endl;}
P>};

P>class B
P>{
P>public:
P>   void f(){ cout << "B::f()" << endl;}
P>};

P>class AB : virtual public A, virtual public B
P>{
P>};


P>int main(int argc, char* argv[])
P>{
P>    A *a = new AB;
P>    B *b = new AB;
    
    a->>f();
    b->>f();
P>  return 0;
P>}
P>


P>А смысл чисто виртуальной функции в том, чтобы возложить реализацию на производный класс:

P>
P>class A
P>{
P>public:
P>   virtual void f() = 0;
P>};

P>class B
P>{
P>public:
P>   virtual void f() = 0;
P>};

P>class AB : virtual public A, virtual public B
P>{
P>public:
P>   void f() {
P>       cout << "f()" << endl;
P>   }
P>};


P>int main(int argc, char* argv[])
P>{
P>    AB *ab = new AB;
    
    ab->>f();
P>  return 0;
P>}
P>


P>Код в вопросе можно поправить так:

P>
P>class A
P>{
P>public:
P>   virtual void fA() = 0;
P>};

P>class B
P>{
P>public:
P>   virtual void fB() = 0;
P>};

P>class AB : public A, public B
P>{
P>public:
P>   void fA() {
P>       cout << "A::fA()";
P>   }
P>   void fB() {
P>       cout << "B::fB()";
P>   }
P>};
P>


P>Или так:

P>
P>class A
P>{
P>public:
P>   void f(){ cout << "A::f()" << endl;}
P>};

P>class B
P>{
P>public:
P>   void f(){ cout << "B::f()" << endl;}
P>};

P>class AB : virtual public A, virtual public B
P>{
P>public:
P>   void f() {
P>       cout << "AB::f()" << endl;
P>   }
P>};

P>int main(){
P>    AB *ab = new AB;
    ab->>f();
    ab->>A::f();
    ab->>B::f();
P>}
P>


P>Кстати gnu-шный компиллятор ругается на этот код по-другому:

P>

P>error: cannot declare member function `A::f' within `AB'
P>error: cannot declare member function `B::f' within `AB'

Re[3]: множественное наследование и полиморфизм
От: poilk  
Дата: 22.09.04 12:11
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Нет, не так.

А>Виртуальное наследование предотвращает создание двух экземпларов базового класса.

А>class Base {};


А>class DerA : public Base {};

А>class DerB : public Base {};

А>class DerDer1 : public DerA, public DerB {}; // Данные класса Base бублируюутся.

А>class DerDer2 : virtual public DerA, virtual public DerB {}; // А тут вроде нет.

Это верно для такого случая:

    Base      Base  Base            
     /  \        |    |
    A    B       A    B            
     \  /         \  /            
  Derive       Derive

согласен.

А>А все варианты, представленные ниже по моему не соответствуют начальной задумке


Зато работают А вообще, соглашусь-ка я с этим
Автор:
Дата: 22.09.04
(со второй частью).
... << RSDN@Home 1.1.4 beta 3 rev. 0>>
Re[4]: множественное наследование и полиморфизм
От: Аноним  
Дата: 22.09.04 12:26
Оценка:
А>>А все варианты, представленные ниже по моему не соответствуют начальной задумке

P>Зато работают А вообще, соглашусь-ка я с этим
Автор:
Дата: 22.09.04
(со второй частью).


Там я переопределил переопределил права доступа к функциям.
Хорошо так делать или нет? Подскажите, кто знает.

А вот маленткая поправка к этому
Автор:
Дата: 22.09.04


class Proxy_X : public X
{

protected:

virtual void f_X() = 0;

private:

void f() { f_X();} // Это чтобы больше никто не смог переписать f().

};
Re[2]: множественное наследование и полиморфизм
От: Аноним  
Дата: 22.09.04 12:47
Оценка:
Здравствуйте, poilk, Вы писали:

P>Здравствуйте, machine1, Вы писали:


M>>Привет,


M>>незнаю как сделать, хотелось что-то типа этого:



M>>
M>>class A
M>>{
M>>public:
M>>   virtual void f() = 0;
M>>};

M>>class B
M>>{
M>>public:
M>>   virtual void f() = 0;
M>>};

M>>class AB : public A, public B
M>>{
M>>public:
M>>   void A::f() {/*тут реализация*/}
M>>   void B::f() {/*тут реализация*/}
M>>}
M>>



А если так:
int main(int argc, char* argv[])
{
AB* ab = new AB;
A *a = ab;
B *b = ab;

a->f();

b->f();
ab->f(); ?? Зачем тогда вообще нужен AB?
return 0;
}

P>
P>class A
P>{
P>public:
P>   void f(){ cout << "A::f()" << endl;}
P>};

P>class B
P>{
P>public:
P>   void f(){ cout << "B::f()" << endl;}
P>};

P>class AB : virtual public A, virtual public B
P>{
P>};


P>int main(int argc, char* argv[])
P>{
P>    A *a = new AB;
P>    B *b = new AB;
    
    a->>f();
    b->>f();
P>  return 0;
P>}
P>





P>А смысл чисто виртуальной функции в том, чтобы возложить реализацию на производный класс:

P>
P>class A
P>{
P>public:
P>   virtual void f() = 0;
P>};

P>class B
P>{
P>public:
P>   virtual void f() = 0;
P>};

P>class AB : virtual public A, virtual public B
P>{
P>public:
P>   void f() {
P>       cout << "f()" << endl;
P>   }
P>};


P>int main(int argc, char* argv[])
P>{
P>    AB *ab = new AB;
    
    ab->>f();
P>  return 0;
P>}
P>


А и В — могут представлять собой совершенно разные интерфейсы.
Скажем A — вывод на экран, B — включение дворников у машины.
Значит реализация должна быть у обеих функций: у A::f() и у B::f().
Т.е. такое решение тоже не подходит.






P>Код в вопросе можно поправить так:

P>
P>class A
P>{
P>public:
P>   virtual void fA() = 0;
P>};

P>class B
P>{
P>public:
P>   virtual void fB() = 0;
P>};

P>class AB : public A, public B
P>{
P>public:
P>   void fA() {
P>       cout << "A::fA()";
P>   }
P>   void fB() {
P>       cout << "B::fB()";
P>   }
P>};
P>


Как я уже сказал — не соответствует начальному условию
(одинаковые сигнатуры функций двух разных базовых классав)



P>Или так:

P>
P>class A
P>{
P>public:
P>   void f(){ cout << "A::f()" << endl;}
P>};

P>class B
P>{
P>public:
P>   void f(){ cout << "B::f()" << endl;}
P>};

P>class AB : virtual public A, virtual public B
P>{
P>public:
P>   void f() {
P>       cout << "AB::f()" << endl;
P>   }
P>};

P>int main(){
P>    AB *ab = new AB;
    ab->>f();
    ab->>A::f();
    ab->>B::f();
P>}
P>



Не катит.
Должна быть реализована каждая из ф-ий A::f() и B::f().
Причем обращение к ним из указателей на A или B не должно меняться, т.к.
у вы не всегда имеете возможность менять базовые классы.


Короче работает все, но это все — не то, что требовалось.





P>Кстати gnu-шный компиллятор ругается на этот код по-другому:

P>

P>error: cannot declare member function `A::f' within `AB'
P>error: cannot declare member function `B::f' within `AB'

Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.