2015-12-03 25 views
7

Mi stavo chiedendo se qualcuno sa se è possibile utilizzare l'ereditarietà all'interno di un sindacato in qualche modo.Utilizzo dell'ereditarietà all'interno di un'unione

Nell'esempio che segue, l'unione TestFails non conterrà la variabile a all'interno del Base struct, mentre TestWorks funziona.

struct Base { int a; }; 

union TestFails 
{ 
    struct : public Base {}; 
    int b; 
}; 

union TestWorks 
{ 
    struct { int a; }; 
    int b; 
}; 

int main() 
{ 
    TestWorks works; 
    works.a = 0; 

    TestFails fails; 
    fails.a = 0; 

    return 0; 
} 

È possibile verificare il codice qui: http://ideone.com/dUzpOR

+0

Per curiosità, perché lo vuoi? – Cameron

+0

Ho alcuni sindacati che necessitano di un po 'di riordino, i cui contenuti sono abbastanza simili, quindi speravo di avere alcune strutture di dati di base che potrei riutilizzare. – Artoo

+0

FWIW, questo sembra non essere specifico per i sindacati: http://ideone.com/9VGAkz – immibis

risposta

0

Non sono sicuro se aiuta, ma questo funziona:

struct Base { int a; }; 
struct Foo : Base { int b;}; 
union TestFailsNot { 
    Base base; 
    Foo foo; 
    int b; 
}; 

int main() { 
    TestFailsNot failsNot; 
    failsNot.foo.a = 0;  
    failsNot.base.a = 3; // maybe not what you want to do, but it works 
} 
+0

@Cameron ha aggiornato la risposta – user463035818

1

Prima di tutto - la vostra ipotesi che TestWorks opere è sbagliato. Questo non è standard C++ - solo l'estensione ad esso - si chiama unnamed anonymous struct - e quando si compila con le opzioni pedanti si ottiene:

prog.cc:5:27: error: ISO C++ prohibits anonymous structs [-Wpedantic]
struct : public Base {};

     ^

prog.cc:11:22: error: ISO C++ prohibits anonymous structs [-Wpedantic]
struct { int a; };

per risolvere il tuo problema - solo il nome queste le strutture anonime :

union TestFails 
{ 
    struct : public Base {} s; 
    //     ^
    int b; 
}; 

union TestWorks 
{ 
    struct { int a; } s; 
    //    ^
    int b; 
}; 
+0

Sapevo che le strutture anonime non erano standard, ma questo è esattamente quello che stavo cercando di evitare come da mio commento sopra. Grazie comunque per il tuo aiuto. – Artoo

1

La risposta è no. Ci sono molti angoli bui in C++ ma questo non è uno di loro :)

le classi e le strutture hanno ereditarietà. i sindacati no.

L'unico modo per realizzare ciò che si sta cercando ... è riconfigurare le unioni di struct (dico le strutture solo perché hanno un ambito pubblico predefinito, quindi non è necessario dichiarare loro pubblico)

Se si tenta di inserire una struttura all'interno del proprio sindacato, sarà necessario aggiungere l'ambito extra della nuova struttura per accedere al suo valore.

Esattamente come la risposta di AndyG mostra questo:

union TestFails 
{ 
    struct foo: public Base {}; 
    foo f; 
    int b; 
}; 

TestFails fails; 
fails.f.a = 42; 
std::cout << fails.f.a << std::endl; 

Se si omette una variabile chiamata e di creare un ambito senza nome che viene fatto con gli spazi dei nomi di tanto in tanto poi i dati non sono accessibili dall'esterno (che è il punto di questo in primo luogo)

+0

L'ereditarietà delle unioni non è in discussione qui, l'ereditarietà interessa una struttura all'interno di un sindacato, che è un problema completamente diverso per quanto ne so. Puoi estendere la tua soluzione usando i namespace? – Artoo

+1

Capisco che l'eredità sindacale non è la tua domanda, ma l'unico modo per raggiungere il tuo obiettivo è l'ereditarietà. Effettuando il refactoring in una struct sarai in grado di accedere al livello 1 di valore nella tua unione in modo tale che tu stia solo accedendo al valore come 'f.a' invece di' f.s.a'. Questo è conforme alla relazione 'is a' vs' has a' cui ci si sta avvicinando dal momento attuale – Dan

+0

Il punto relativo agli spazi dei nomi anonimi va di pari passo con qualsiasi altro anonimo/non specificato. Non sono fatti per essere accessibili esternamente o sono temporanei. – Dan