#1 05.04.06 18:17
[C++] Проблема наследования
Программа при компиляции выдаёт сообщения:
1) Main.cpp(23) : error C2248: 'MyFunk' :
cannot access protected member declared in class 'A'
Main.cpp(9) : see declaration of 'MyFunk'
2) Main.cpp(38) : error C2248: 'MyFunk' :
cannot access protected member declared in class 'B'
Main.cpp(18) : see declaration of 'MyFunk'
Код: C++:
#include <iostream> using namespace std; class B; class C; class A{ protected:// Диспетчерские Функции двойной передачи virtual void MyFunk(B*)=0; virtual void MyFunk(C*)=0; public: // Пользовательские Функции двойной передачи virtual void MyFunk(A*)=0; }; class B: public A{ protected:// Диспетчерские Функции двойной передачи virtual void MyFunk(B*Bptr){ cout<<"Bptr(B*) to this(B*).\n";}; virtual void MyFunk(C*Cptr){ cout<<"Cptr(C*) to this(B*).\n";}; public: // Пользовательские Функции двойной передачи virtual void MyFunk(A*Aptr){ Aptr->MyFunk(this);}; }; class C: public A{ protected:// Диспетчерские Функции двойной передачи virtual void MyFunk(B*Bptr){ cout<<"Bptr(B*) to this(C*).\n";}; virtual void MyFunk(C*Cptr){ cout<<"Cptr(C*) to this(C*).\n";}; public: // Пользовательские Функции двойной передачи virtual void MyFunk(A*Aptr){ Aptr->MyFunk(this);}; }; int main(){ B *Bptr=new B; C *Cptr=new C; Bptr->MyFunk(Bptr); return 0; }
Вопрос:
1)Разве при наследовании класса B от A функция
virtual void A::MyFunk(B*)=0;
не переходит в protected функцию класса B?
По всем моим представлениям это должно компиляться и так, а компиляется только при замене protected на public в классе A.
2)При устранении п.1 компилятор в main-е хочет явного преобразования Bptr к (A*)Bptr, хотя указатель производного класса должен автоматически преобразовывалься к указателю на базовый.
Offline
#4 05.04.06 22:13
Re: [C++] Проблема наследования
LeoT написал(а):
2)При устранении п.1 компилятор в main-е хочет явного преобразования Bptr к (A*)Bptr, хотя указатель производного класса должен автоматически преобразовывалься к указателю на базовый.
хм..... должен, но не в этом случае. В классе объявлены функции, которые по сигнатуре параметров полностью совпадают с вызовом, необходимости в приведении нет.
Offline
#5 05.04.06 22:18
Re: [C++] Проблема наследования
Для разъяснения ситуации хочу сказать, что
при наследовании
Код: C++:
B: public A{};
происходит следующее:
из A public переходит в B public,
из A protected переходит в B private,
из A private в B члены недоступны.
То есть y меня protected void A::MyFunk(B*) окажется в private B, но для виртуальных функций(возможно только для чисто виртуальных), допустимо переопределение области видимости, так что должно работать.
Offline
#6 05.04.06 22:22
Re: [C++] Проблема наследования
LeoT, слухай, а с чего это должно компилироваться то? :)
в общедоступной функции
virtual void B::MyFunk(A*Aptr){ Aptr->MyFunk(this);};
указатель this какой тип имеет? пральна, *B. А в классе А какая функция с таким параметром? Пральна, protected.... А вызов ее идет НЕ ИЗ КЛАССА, а по указателю, т.е. фактически - извне. ПОтому она и не доступна.
Явным перобразованием типов проблема решается. virtual void B::MyFunk(A*Aptr){ Aptr->MyFunk((A*)this);};
Offline
#7 06.04.06 00:19
Re: [C++] Проблема наследования
Потихоньку врубаюсь, Andron_, но всёже virtual void B::MyFunk(A*Aptr){Aptr->MyFunk((A*)this)} не выход, так как в данной программе приводит к рекурсии, т.е. ПОЛНОМУ зацикливанию.
А вот Bptr->MyFunk((A*)Bptr) в main-е выглядит не сексуально, можноли это забороть?
ToAll: Кстати Sorry, protected переходит в protected.
Offline
#8 06.04.06 01:02
Re: [C++] Проблема наследования
LeoT написал(а):
но всёже virtual void B::MyFunk(A*Aptr){Aptr->MyFunk((A*)this)} не выход, так как в данной программе приводит к рекурсии, т.е. ПОЛНОМУ зацикливанию.
а иначе никак, если это не работает, значит, имхо, программа в приципе неверно построена....
Можно защищенные функции сделать общедоступными... ну никак иначе....
LeoT написал(а):
А вот Bptr->MyFunk((A*)Bptr) в main-е выглядит не сексуально, можноли это забороть?
Объяви переменные как указатели на базовый класс. У тебя класс абстрактный - ничего не изменится в работе.
A *Bptr=new B;
A *Cptr=new C;
P.S. а что это вообще за задача? :)
Offline

