2017-05-25 20 views
19

Widziałem anonimowych klas w C++ kod na Quora. Został skompilowany i uruchomiony.Czy można używać klas anonimowych w C++?

kod tutaj:

#include <iostream> 

auto func() 
{ 
    class // no name 
    { 
     public: 
      int val; 
    } a; 

    a.val = 5; 

    return a; 
} 

int main() 
{ 
    std::cout << func().val << std::endl; 
    return 0; 
} 

Więc Czy to ważne w C++?

Ponadto, jestem ciekaw, Czy można używać anonimowych klas w C++?

+3

To było [wcześniej pytano] (https://stackoverflow.com/questions/3612164/c-anonymous-class-initialization) –

+1

C++ ma [anonimowe związki] (http://eel.is/c++ draft/class.union.anon), ale bez anonimowych klas/struktur, które niektóre kompilatory dostarczają jako rozszerzenie. Mimo to, nienazwane klasy przedstawione w pytaniu są prawidłowe. – cpplearner

+1

@cpplearner anonymius union jest członkiem klasy * typu unii, który nie ma nazwy (członek, a nie typ). –

Odpowiedz

16

W C++ anonimowa unia jest związkiem tego formularza:

union { ... } ; 

Definiuje anonimowego obiekt typu bezimiennego. Jego członkowie są wstrzykiwani w otaczającym zakresie, więc można się do nich odnieść bez użycia prefiksu <object>., który w przeciwnym razie byłby potrzebny.

Istnieje w tym sensie, że nie istnieją żadne anonimowe klasy (które nie są związkami zawodowymi - w C++ są klasami).

Z drugiej strony, nienazwane klasy (w tym struktury i związki) nie są niczym niezwykłym.

union { ... } x; 
class { ... } y; 
typedef struct { ... } z; 

x i y nazywane są przedmiotem nienazwanych typów. z to nazwa typu, która jest aliasem dla nienazwanej struktury. Nie nazywa się ich anonimowymi, ponieważ ten termin jest zarezerwowany dla powyższej formy związku.

[](){} 

Lambdas to nienazwane obiekty o nienazwanych typach klas, ale nie nazywa się ich również anonimowymi.

+0

Czy lambdy typu 'std :: function'? –

+3

@DonaldDuck nie, są one zamienialne na std :: function, ale każda lambda ma swój unikalny typ. –

+0

@DonaldDuck Nie, mają zdefiniowany typ implementacji. 'std :: function' używa typu-erasure do powiązania z dowolną klasą/funkcją, która może być wywołana jak funkcja, np. obiekt funkcji, na przykład lambda. – Rakete1111

31

Co więcej, można utworzyć więcej instancji klasy za pomocą decltype.

#include <iostream> 

class 
{ 
    public: 
     int val; 
} a; 


int main() 
{ 
    decltype(a) b; 
    a.val = 10; 
    b.val = 20; 

    std::cout << a.val << std::endl; 
    std::cout << b.val << std::endl; 
    return 0; 
} 

wyjściowa:

10 
20 
+1

Czy to prawda, że ​​przed C++ 11 nie było sposobu zadeklarować innego wystąpienia nienazwanej klasy? – lisyarus

+4

@lisyarus: Było to możliwe z szablonem takim jak 'template T create (const T & prototype) {return T(); } ' –

+0

@AlexandreC. Ale jak przypisać wynik "create" do zmiennej lokalnej, jeśli nie mam dostępu do typu (poza 'create')? – lisyarus

9

To zawsze było to możliwe, aby napisać coś takiego:

typedef struct { int a; } type; 

Teraz, jeśli spojrzeć na struct { int a } części jest to anonimowy struct. W C++ zasadniczo nie ma różnicy między strukturami i klasami (z wyjątkiem domyślnych modyfikatorów dostępu). Tak więc możliwe jest posiadanie anonimowych struktur/klas.

Powiązane problemy