[C++] Przyjaźń a klasy zagnieżdżone


(Quentin) #1

Witam!

Projektuję sobie aktualnie pewien program i mam pytanie dotyczące deklaracji przyjaźni.

Jeżeli klasa K deklaruje przyjaźń z klasą PRZ to tym samym deklaruje przyjaźń z klasami zagnieżdżonymi w klasie PRZ :?: Bo dwa dość zgodne ze standardem kompilatory - g++ i Comeau C++ Online różnie to rozpatrują. W g++ tak się nie dzieje, a wg Comeau tak jest.

Chodzi mi o coś takiego:

class K{    typedef int cena;

(Marcin 110) #2

ISO/IEC 14882:2003(E) 11.4.2 mówi:

class A {

  class B { };

  friend class X;

};


class X : A::B { // ill-formed: A::B cannot be accessed

                           // in the base-clause for X

  A::B mx; // OK: A::B used to declare member of X

  class Y : A::B { // OK: A::B used to declare member of X

    A::B my; // ill-formed: A::B cannot be accessed

                           // to declare members of nested class of X

  };

};

ostatni deklaracja A::B my to chyba to, a jeśli pozbędziemy się pierwszego błędu (dziedziczenia X po A::B), to zarówno Cameau jak i g++ to przepuszczają... a przecież to fragment standardu. EDIT: trochę się pospieszyłem z oceną. EDIT2: Chyba wyjaśnię tu część sprawy. W szkicu nowego standardu C++ w pkt. 11.4.2 stoi zupełnie inaczej:

class A {

  class B { };

  friend class X;

};


struct X : A::B { // OK: A::B accessible to friend

  A::B mx; // OK: A::B accessible to member of friend

  class Y {

    A::B my; // OK: A::B accessible to nested member of friend

  };

};

To tłumaczy g++, które powoli przyswaja nowy standard, ale dla Cameau z opcją "Compile in strict C++03 mode" to nie jest żadne uzasadnienie.


(Quentin) #3

To znaczy, że dane prywatne klasy, która wyraziła przyjaźń mogą być użyte na liście dziedziczenia w klasie zagnieżdżonej w klasie zaprzyjaźnionej :?: :lol:

No pospieszyłeś, się bo g++ tego nie przepuści już :slight_smile: Tylko Comeau...


(Marcin 110) #4

Część dopisałem do poprzedniego postu. Mam g++ w wersji 4.4.3 i przepuszcza.

Na początku pobieżnie zerknąłem i z tego to wyszło. Masz dostęp do historii edycji :?:


(Quentin) #5

Chyba się nie zrozumieliśmy - chodziło mi o to czy ja to dobrze przetłumaczyłem :slight_smile:

base-specifiers to lista dziedziczenia :?:

Klasa zagnieżdżona w zaprzyjaźnionej to nie do końca befriended, ale OK - już się nie zagłębiam. Skoro w C++0x deklaracja przyjaźni obejmuje "wszystko z góry na dół" to nie mam więcej pytań :slight_smile:


(Marcin 110) #6

Tak (dokładniej base-specifier-list), wszystko jest dokładniej omówione w rozdziale 10. standardu.

Ale tu chodzi o jej deklarację. Choć klasa zagnieżdżona jest częściowo niezależnym bytem, to nadal jest traktowana jako członek "klasy zawierającej" (ang. enclosing class) i jest traktowana podobnie jak metoda czy dane (ang. data members). Mówi to jasno punkt 9.2.1.

W C++03 w pkt. 11.8.1 pojawia się:

W C++0x, natomiast jest jedynie:

Pewnie stąd te wymienione wyjątki w pkt. 11.4.2 i specjalne traktowanie klas zagnieżdżonych w starym standardzie.


(Quentin) #7

No i jeszcze base-clause też oznacza listę dziedziczenia.

OK to dzięki za pomoc :slight_smile: Podsumowując: w C++0x klasa zagnieżdżona jest traktowana jako normalna dana składowa klasy i dlatego może uzyskiwać dostęp do danych prywatnych klasy wyrażającej przyjaźń.

--------------------------------------------------------------------------------------

EDIT 09.07.2010:

Mam jeszcze 2 pytanka małe :slight_smile:

Pytanie 1) Odnośnie klasy zagnieżdżonej w C++0x - na jej liście dziedziczenia też będzie można prawdopodobnie używać składników prywatnych klasy wyrażającej przyjaźń, prawda :?: Bo w przykładzie C++0x 11.4.2 nie jest o tym wspomniane...

Pytanie 2)

Od kiedy pojedyncze funkcje wyrażają przyjaźń :?: :smiley: