[Megoldva] Protected függvény hívása

Fórumok

Sziasztok.

A következő a gondom:
Adott két osztály, az ős, annak egy protected, tisztán virtuális függvénye, illetve a leszármazott, amely implementálja ezt a függvényt, és ugyanebben az osztályban egy másik függvényben kapott ős típusú paraméterre meg akarja hívni a protected függvényt.

A fordító közölte velem, hogy ez így nem fog menni:
class.cc: In member function ‘void B::g(const A&)’:
class.cc:7: error: ‘virtual void A::f() const’ is protected
class.cc:13: error: within this context

Azt szeretném megkérdezni, hogy hogyan tudom megoldani a problémát.

A kód nagyon leegyszerűsítve valami ilyesmi:


#include < iostream >

class A
{
protected:
virtual void f() const = 0;
};

class B: public A
{
public:
void g( const A& a ) { a.f(); }
protected:
virtual void f() const { std::cout << "Ok" << std::endl; }
};

int main()
{
B a, b;

b.g( a );

return 0;
}

Hozzászólások

nem csak annyi a gond, hogy a B-bol hivod A osztaly protected fuggvenyet?
az ugyse csinal semmit, inkabb a B-ben megvalositott leszarmaztatott veriojat akarod hivni, nem?
persze nem ertek C++hoz.

Tyrael

Az A-ban levő függvény egy absztakt függvény, és a gond az, hogy a paraméter lehet, B, C, D, stb is, bármi, ami A-ból származik.
Legalábbis én így gondoltam.

"If you must mount the gallows, give a jest to the crowd, a coin to the hangman, and make the drop with a smile on your lips" The Wheel of Time series

Hát ezt így úgy tűnik nem lehet.

f protected, ami azt jelenti, hogy a leszármazottak hívhatják, a külvilág nem.

Itt ugyan egy leszármazottról van szó, és nyilván a saját f-jét hívhatná is, de így nem. (Azt most hirtelen nem látom ez miért logikus így, de tuti ez a szabvány.)

Ha neked ilyen kell, akkor az tervezési hiba.
Nyilvánvaló megoldás, hogy f legyen public, de sokan nem szeretik, ha a virtuális fv public, a szakirodalom se ajánlja.

Ezért szokták ezt csinálni:


#include <iostream>

class A
{
public:
void callF() const { f(); }
protected:
virtual void f() const = 0;
};

class B: public A
{
public:
void g( const A& a ) { a.callF(); }
protected:
virtual void f() const { std::cout << "Ok" << std::endl; }
};

int main()
{
B a, b;

b.g( a );
a.callF();

return 0;
}

Ezt rengeteg helyen látni, pl Qt-ben az összes QWidget eseménykezelő így van megoldva...

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

Tudom, UTFG, de alapvetően lusta vagyok; és köszönöm, hogy UTFG helyett egy megoldást adtál, illetve egy magyarázatot is.

Bízok benne, hogy idővel túljutok azon, hogy az a bizonyos "csimpánz" legyek. :)

"If you must mount the gallows, give a jest to the crowd, a coin to the hangman, and make the drop with a smile on your lips" The Wheel of Time series

Nagyon egyszeru: Amikor A-kent veszi at, akkor kulso hivas van. Ha onmagaban hivna a f()-et, akkor mukodne a dolog, de igy external hivasnak kezelodik le asszem.
Es nem is illik ilyen modon lathatosagot emelni. azaz a public->protected->private irany engedett, a visszaut nem.
--


()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.