Domanda

Qualcuno sa perché typedef di nomi di classi non funzionano come nomi di classe per la dichiarazione amico?

class A
{
public:
};

class B : public A
{
public:
   typedef A SUPERCLASS;
};

typedef A X;

class C
{
public:
   friend class A;             // OK
   friend class X;             // fails
   friend class B::SUPERCLASS; // fails
};
È stato utile?

Soluzione

Non si può, al momento. Non so il motivo ancora (solo guardando in su, perché lo trovo interessante). Aggiornamento: è possibile trovare il motivo nella prima proposta di sostenere typedef-nomi come amici: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1520.pdf . Il motivo è che lo standard supportato solo elaborati-type-committenti. E 'facile per consentire solo quelli, e dire se l'entità dichiarata come amico non è ancora dichiarato, sarà reso un membro dello spazio dei nomi circostante. Ma questo significa che se si desidera utilizzare un parametro di template, si dovrebbe fare (è richiesta una classe poi per esempio)

friend class T;

Ma che ha portato ulteriori problemi, ed è stato capito non vale il guadagno. Ora, il documento propone di consentire specificatori di tipo complementari da fornire (in modo che questo allora permette l'uso di parametri di modello e typedef nomi).

La prossima versione C ++ (a causa di 2010) sarà in grado di farlo.

Vedere questa proposta aggiornata allo standard: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1791.pdf . Non solo consentirà typedef nomi, ma anche i parametri di modello da utilizzare come il tipo dichiarato come amico.

Altri suggerimenti

AFAIK, In C ++ typedef non crea sinonimi pieno titolo quando usato in congiunzione con le classi. In altre parole, non è come una macro.

Tra le restrizioni è che il sinonimo non può apparire dopo il prefisso classe o struct, o essere utilizzato come nome distruttore o costruttore. Non è inoltre possibile creare una sottoclasse il sinonimo. Sono pronto a scommettere che si significa anche non è possibile che amico.

ho provato nel VC ++ 8.0 il codice:

...
class C
{
public:
  friend class A;       
  friend X;             
  friend B::SUPERCLASS; 
};
...

E 'stato compilato senza errori.

Non sono a conoscenza se è MS specifica o meno.

Un typedef definisce un tipo. Amico decls dichiarare classi amico o funzioni (Scopes sostanzialmente), che poi hanno "accesso" per l'area non pubblica della classe dichiarando ...

Primitives, vale a dire un galleggiante o un int * non definiscono un ambito con il codice ecc, non "usare" la classe in ogni modo.

Non dimenticare, è anche possibile "pacchetto" convenzioni di chiamata, attribs allineamento e cose specifiche altro compilatore in un typedef, vale a dire più tipi di vettore attuati dalla stessa classe ma con attribs allineamento distinte. => Un tipo non è una classe, ma viceversa.

IMHO, dichiarando un amico typedef può essere utile, ma quando "typedef di classe" da qualsiasi luogo possono essere impostati come amico, le amicizie può diventare estremamente incomprensibile e quindi soggetto a errori, specialmente dove i modelli vengono utilizzati eccessivamente.

Annullamento un'unica typedef può rovinare l'intero progetto a causa di dipendenze diffuse. amici dei modelli e le typedef template 0x sono utili, ma non rilassarsi le regole di una dichiarazione amico.

Non so di qualsiasi proposta relativa amico typedef.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top