2015-12-03 26 views
7

Zastanawiałem się, czy ktoś wie, czy można w jakiś sposób wykorzystać dziedziczenie w związku.Korzystanie z dziedziczenia w ramach związku

W poniższym przykładzie, związek TestFails nie będzie zawierać zmienną wewnątrz Base struct a, natomiast TestWorks działa.

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; 
} 

można przetestować kod tutaj: http://ideone.com/dUzpOR

+0

Z ciekawości, dlaczego tego chcesz? – Cameron

+0

Mam kilka związków, które wymagają trochę sprzątania, które są bardzo podobne, więc miałem nadzieję, że będę miał kilka podstawowych struktur danych, które będę mógł ponownie wykorzystać. – Artoo

+0

FWIW, wydaje się, że nie jest to specyficzne dla związków: http://ideone.com/9VGAkz – immibis

Odpowiedz

0

Nie wiem, czy to pomoże, ale to działa:

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 zaktualizował odpowiedź – user463035818

1

Przede wszystkim - swoje założenie, że TestWorks dzieła jest źle. To nie jest standard C++ - tylko rozszerzenie do niego - to się nazywa unnamed anonymous struct - i podczas kompilacji z opcji pedantycznego otrzymasz:

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; };

Aby rozwiązać swój problem - wystarczy wymienić te anonimowe konstrukcjom :

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

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

Wiedziałem, że anonimowe konstrukcje nie są standardowe, ale dokładnie to starałem się uniknąć, jak na mój komentarz powyżej. Mimo wszystko, dziękuję za twoją pomoc. – Artoo

1

Odpowiedź brzmi: nie. Istnieje wiele ciemnych kątów w C++, ale to nie one :)

Klasy i konstrukcje dziedziczą. związki zawodowe nie.

Jedynym sposobem, aby osiągnąć to, co próbujesz ... to byłaby swoje związki do kodowanym (mówię kodowanym tylko dlatego, że mają domyślny zakres publicznego, więc nie trzeba zadeklarować je do wiadomości publicznej)

Jeśli spróbujesz umieścić strukturę wewnątrz swojego związku, musisz dodać dodatkowy zakres nowej struktury, aby uzyskać dostęp do jej wartości.

Dokładnie jak odpowiedź AndyG pokazuje to:

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

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

Jeśli pominąć zmienną o nazwie i utworzyć nienazwany zakres który odbywa się z przestrzeniami nazw sporadycznie następnie dane te nie mogą być dostępne z zewnątrz (co jest punktem tego na pierwszym miejscu)

+0

Dziedziczenie związków nie jest tutaj omawiane, dziedziczenie wpływa na strukturę w ramach związku, co jest zupełnie innym zagadnieniem, o ile mi wiadomo. Czy możesz rozszerzyć swoje rozwiązanie za pomocą przestrzeni nazw? – Artoo

+1

Rozumiem, że dziedziczenie związków nie jest pańskim pytaniem, ale jedynym sposobem osiągnięcia celu jest dziedziczenie. Przez refaktoryzację do struktury będziesz mógł uzyskać dostęp do poziomu wartości 1 w głąb swojego związku, tak że uzyskujesz dostęp do wartości tylko jako "f.a" zamiast 'f.s.a'. Jest to zgodne z relacją 'jest' w porównaniu z relacją 'ma a', z którą obecnie się zbliżasz. – Dan

+0

Punkt dotyczący nienazwanych przestrzeni nazw pasuje do czegoś innego anonimowo/bez nazwy. Nie mają one być dostępne na zewnątrz lub są tymczasowe. – Dan