Ĺadny brzuch
Siema, mam kilka spraw odnosnie deklaracji przyjaźni w klasach :) Uczę się z książki "Symfonia C++ standard".
Pierwsza rzecz to taki kod podany przez autora:
class druga; //<--- deklaracja zapowiadająca class pierwsza{ friend class druga; }; class druga{ friend class pierwsza; };
Pierwsza linijka - sprawdzilem - jest zbędna prawda ? Bo dekl. zapowiadająca jest jednocześnie w deklaracji przyjaźni jakby w liniii 3.
Druga sprawa to deklaracja przyjaźni z jakąś funkcją składową. Jeżeli np. klasa X definiuje przyjaźń z funkcją PRZ::fun to klasa PRZ musi być już wcześniej zdefiniowana. Grębosz wspomniał, że tak jest zeby np. sprawdzic czy taka funkcja rzeczywiście tam jest. Są jeszcze inne argumenty ?
Trzecia sprawa łączy się z powyższą. Jeżeli mamy taką sytuację jak wyżej to funkcja PRZ::fun musi być zdefiniowana na zewnątrz klasy PRZ, po definicji klasy X, prawda ? Bo skoro w swoim ciele korzysta ze skladnikow tej klasy X, to X musi być już zdefiniowana, tak ?
Czwarta sprawa dotyczy specyfikatora 'static'. W Symfonii jest napisane:
Może się tak zdarzyć, że kompilator (pracując nad jakimś plikiem) zobaczy deklaracje jakiejś funkcji po raz pierwszy dopiero w miejscu deklaracji przyjaźni. Nie jest to błąd, ale uwaga: w tym miejscu kompilator uzna, że chodzi o jakąś funkcję dostępną ogólnie - także z innych plików tego programu.
Jeśli jednak zostanie przez nas oszukany, to znaczy gdzieś dalej zobaczy, że definiujemy tę funkcję jako funkcję statyczną (czyli widzialną tylko dla tego jednego konkretnego pliku) - zasygnalizuje błąd.
Nie byłoby problemu gdybyśmy wcześniej zamieścili deklarację tej funkcji jako statycznej - bo wtedy, przy deklaracji przyjaźni, kompilator już wiedziałby, z czym ma do czynienia i nie musiałby niczego zakładać w ciemno, a potem zmieniać zdanie.
Czyli aby funkcja posiadała łączenie wewnętrzne i była przyjacielem klasy to powinna znaleźć się nad definicją danej klasy:
static void fun(int, int) { } class A { friend void fun(int, int); };
Zgadza się ?
Piąta i ostatnia sprawa dot. tego fragmentu z ksiązki:
W deklaracji przyjaźni nie mogą pojawić się przydomki (specyfikatory) określające sposób, w jaki przyjaciel został (przez kompilator) umieszczony w pamięci. Te niedozwolone przydomki to: static, auto, register, extern, mutable.
Pomijając fakt, ze autor się pomylił tutaj, bo nigdy nie ma takich przydomków przed funkcją jak mutable, register i auto - to dlaczego static i extern są zabronione ?
Dzięki za pomoc :]
Trochę nie rozumiem twoich pytań.
W punkcie pierwszym - nie wiem, czy pierwsza linijka jest niepotrzebna, ale zdecydowanie nie przeszkadza i nie wpływa na szybkość wykonania programu itp. więc chyba nie ma co dociekać.
W punkcie drugim - po co Ci inne argumenty? Jeden chyba wystarczy ;)
Punkt trzeci - nie szybciej by było to po prostu skompilować i sprawdzić czy działa?
Czwarty - nie jestem w stanie zrozumieć po co jest ten static przed funkcją, skoro nie jest to metoda klasy.
Piąty - autor się moim zdaniem nie pomylił, tylko pisał o przyjaźni z klasą, a nie z funkcją.
A tak generalnie ode mnie. Fajnie, że podchodzisz do nauki tak skrupulatnie, ale chyba nie warto poświęcać tyle uwagi "przyjaźni", bo to mechanizm, którego używa się w ostateczności i poza drobnymi wyjątkami (jak np przeładowanie funkcji operator>>(), aby można było zrobić cout << mojaKlasa itd.), to można się bez niego obejść.
Czwarty - nie jestem w stanie zrozumieć po co jest ten static przed funkcją, skoro nie jest to metoda klasy.
static przed funkcją globalną sprawia, że ma ona internal linkage.
Piąty - autor się moim zdaniem nie pomylił, tylko pisał o przyjaźni z klasą, a nie z funkcją.
Od kiedy przy przyjaźni z klasą używa się jakichkolwiek przydomków ?
static przed funkcją globalną sprawia, że ma ona internal linkage.
aha..
Od kiedy przy przyjaźni z klasą używa się jakichkolwiek przydomków ?
W deklaracji przyjaźni nie mogą pojawić się przydomki(...)
Czy widzisz tu sprzeczność?
Czy widzisz tu sprzeczność?
To ja raczej powinienem zadać to pytanie...
To ja raczej powinienem zadać to pytanie...
Oj no dobrze, to od początku. Kolega bob34 zacytował pana Grębosza i w cytacie tym dowiadujemy się, że "W deklaracji przyjaźni nie mogą pojawić się przydomki" i ja zasugerowałem, że podejrzewam, że autorowi chodziło o przyjaźń między klasami, a nie klasą i funkcją (oczywiście mogę się mylić, to są moje podejrzenia, a książki tej nie widziałem już wiele lat). Ty, drogi Quentinie, napisałeś "Od kiedy przy przyjaźni z klasą używa się jakichkolwiek przydomków ?" na co ja odparłem - może nie wprost - że przecież dokładnie to wynika z tego cytatu (pana Grębosza).
Zakończmy już tę nic nie wnoszącą dyskusję, bo moderatorzy przeniosą wątek do śmietnika. Pozdrawiam.
zanotowane.pl doc.pisz.pl pdf.pisz.pl zsf.htw.pl
Pierwsza rzecz to taki kod podany przez autora:
class druga; //<--- deklaracja zapowiadająca class pierwsza{ friend class druga; }; class druga{ friend class pierwsza; };
Pierwsza linijka - sprawdzilem - jest zbędna prawda ? Bo dekl. zapowiadająca jest jednocześnie w deklaracji przyjaźni jakby w liniii 3.
Druga sprawa to deklaracja przyjaźni z jakąś funkcją składową. Jeżeli np. klasa X definiuje przyjaźń z funkcją PRZ::fun to klasa PRZ musi być już wcześniej zdefiniowana. Grębosz wspomniał, że tak jest zeby np. sprawdzic czy taka funkcja rzeczywiście tam jest. Są jeszcze inne argumenty ?
Trzecia sprawa łączy się z powyższą. Jeżeli mamy taką sytuację jak wyżej to funkcja PRZ::fun musi być zdefiniowana na zewnątrz klasy PRZ, po definicji klasy X, prawda ? Bo skoro w swoim ciele korzysta ze skladnikow tej klasy X, to X musi być już zdefiniowana, tak ?
Czwarta sprawa dotyczy specyfikatora 'static'. W Symfonii jest napisane:
Może się tak zdarzyć, że kompilator (pracując nad jakimś plikiem) zobaczy deklaracje jakiejś funkcji po raz pierwszy dopiero w miejscu deklaracji przyjaźni. Nie jest to błąd, ale uwaga: w tym miejscu kompilator uzna, że chodzi o jakąś funkcję dostępną ogólnie - także z innych plików tego programu.
Jeśli jednak zostanie przez nas oszukany, to znaczy gdzieś dalej zobaczy, że definiujemy tę funkcję jako funkcję statyczną (czyli widzialną tylko dla tego jednego konkretnego pliku) - zasygnalizuje błąd.
Nie byłoby problemu gdybyśmy wcześniej zamieścili deklarację tej funkcji jako statycznej - bo wtedy, przy deklaracji przyjaźni, kompilator już wiedziałby, z czym ma do czynienia i nie musiałby niczego zakładać w ciemno, a potem zmieniać zdanie.
Czyli aby funkcja posiadała łączenie wewnętrzne i była przyjacielem klasy to powinna znaleźć się nad definicją danej klasy:
static void fun(int, int) { } class A { friend void fun(int, int); };
Zgadza się ?
Piąta i ostatnia sprawa dot. tego fragmentu z ksiązki:
W deklaracji przyjaźni nie mogą pojawić się przydomki (specyfikatory) określające sposób, w jaki przyjaciel został (przez kompilator) umieszczony w pamięci. Te niedozwolone przydomki to: static, auto, register, extern, mutable.
Pomijając fakt, ze autor się pomylił tutaj, bo nigdy nie ma takich przydomków przed funkcją jak mutable, register i auto - to dlaczego static i extern są zabronione ?
Dzięki za pomoc :]
Trochę nie rozumiem twoich pytań.
W punkcie pierwszym - nie wiem, czy pierwsza linijka jest niepotrzebna, ale zdecydowanie nie przeszkadza i nie wpływa na szybkość wykonania programu itp. więc chyba nie ma co dociekać.
W punkcie drugim - po co Ci inne argumenty? Jeden chyba wystarczy ;)
Punkt trzeci - nie szybciej by było to po prostu skompilować i sprawdzić czy działa?
Czwarty - nie jestem w stanie zrozumieć po co jest ten static przed funkcją, skoro nie jest to metoda klasy.
Piąty - autor się moim zdaniem nie pomylił, tylko pisał o przyjaźni z klasą, a nie z funkcją.
A tak generalnie ode mnie. Fajnie, że podchodzisz do nauki tak skrupulatnie, ale chyba nie warto poświęcać tyle uwagi "przyjaźni", bo to mechanizm, którego używa się w ostateczności i poza drobnymi wyjątkami (jak np przeładowanie funkcji operator>>(), aby można było zrobić cout << mojaKlasa itd.), to można się bez niego obejść.
Czwarty - nie jestem w stanie zrozumieć po co jest ten static przed funkcją, skoro nie jest to metoda klasy.
static przed funkcją globalną sprawia, że ma ona internal linkage.
Piąty - autor się moim zdaniem nie pomylił, tylko pisał o przyjaźni z klasą, a nie z funkcją.
Od kiedy przy przyjaźni z klasą używa się jakichkolwiek przydomków ?
static przed funkcją globalną sprawia, że ma ona internal linkage.
aha..
Od kiedy przy przyjaźni z klasą używa się jakichkolwiek przydomków ?
W deklaracji przyjaźni nie mogą pojawić się przydomki(...)
Czy widzisz tu sprzeczność?
Czy widzisz tu sprzeczność?
To ja raczej powinienem zadać to pytanie...
To ja raczej powinienem zadać to pytanie...
Oj no dobrze, to od początku. Kolega bob34 zacytował pana Grębosza i w cytacie tym dowiadujemy się, że "W deklaracji przyjaźni nie mogą pojawić się przydomki" i ja zasugerowałem, że podejrzewam, że autorowi chodziło o przyjaźń między klasami, a nie klasą i funkcją (oczywiście mogę się mylić, to są moje podejrzenia, a książki tej nie widziałem już wiele lat). Ty, drogi Quentinie, napisałeś "Od kiedy przy przyjaźni z klasą używa się jakichkolwiek przydomków ?" na co ja odparłem - może nie wprost - że przecież dokładnie to wynika z tego cytatu (pana Grębosza).
Zakończmy już tę nic nie wnoszącą dyskusję, bo moderatorzy przeniosą wątek do śmietnika. Pozdrawiam.