2012-04-09 40 views
14

Hay una característica llamada clase anónima en C++. Es similar con la estructura anónima en C. Creo que esta característica se inventó debido a algunas necesidades, pero no puedo entender qué es eso.¿Cuándo necesito una clase anónima en C++?

¿Puedo tener algún ejemplo que realmente necesite una clase anónima?

+1

¿Por qué tienen estructura anónima? – Nawaz

+0

@Nawaz Ah sí, tienes razón. Podría ser la misma razón por la que existe en C. De todos modos, tengo curiosidad sobre los casos específicamente para C++. Debido a que C++ es un lenguaje muy diferente con C. – Eonil

Respuesta

19

La función está ahí porque struct y class son lo mismo: cualquier cosa que se pueda hacer con una, se puede hacer con la otra. Sirve exactamente el mismo propósito que un anónimo struct en C; cuando desee agrupar algunas cosas y declarar una o más instancias de la misma, pero no es necesario que haga referencia a ese tipo por su nombre.

Se usa menos comúnmente en C++, en parte porque los diseños C++ tienden a estar más orientados a los tipos, y en parte porque no se pueden declarar constructores o destructores para las clases anónimas.

2

Tal vez a veces era útil para hacer funciones anidadas como:

void foo() { 
    class { 
    void operator()(){ 
    } 
    } bar; 
    bar(); 
} 

Pero ahora tenemos lambdas y clases anónimas se dejan sólo por razones de compatibilidad.

4

No es realmente necesario en un sentido estricto y nunca lo fue. Es decir. siempre se puede asignar un nombre, por ejemplo anonymous1, anonymous2 etc. Pero hacer un seguimiento de más nombres de los necesarios siempre es una molestia.

Donde es útil es en cualquier lugar donde uno quiera agrupar datos sin darle un nombre a ese grupo. Podría llegar a un varios ejemplos:

class foo { 
    class { 
    public: 
    void validate(int x) { m_x = x; } 
    bool valid() { return m_exists; } 
    private: 
    int m_x; 
    bool m_exists; 
    } maybe_x; 
}; 

En este caso el int y la bool lógicamente pertenecen juntos, así que tiene sentido para agruparlos. Sin embargo, para este ejemplo concreto, probablemente tenga sentido crear un tipo opcional real o utilizar uno de los disponibles, ya que este patrón probablemente también se use en otros lugares. En otros casos, este patrón de agrupación podría ser tan especial, que merece permanecer solo en esa clase.

Realmente asumo, que las clases anónimas raramente se usan (solo las he usado un par de veces en mi vida, probablemente). A menudo, cuando uno quiere agrupar los datos, esto no es específico de la clase o el alcance, sino también una agrupación que también tiene sentido en otros lugares.

+1

Su ejemplo necesitaría un constructor para garantizar la invariante de clase (que el valor sea válido o que el indicador sea falso); pero no puedes declarar un constructor para una clase anónima. –

+0

@MikeSeymour: buen punto. Supongo que uno debería ocuparse de esto de otra manera. Tal vez con C++ 11 en el inicializador de clase esto haría. Como dije, es muy probable que esta sea una característica que se usa muy poco. – LiKao

1

El uso de clases anónimas es para preservar la compatibilidad con el código C existente. Ejemplo:

En algunos códigos C, prevalece el uso de typedef junto con estructuras anónimas.

1

No es un ejemplo de estructuras anónimas que se puede utilizar con el sistema de señal/ranura de Qt 5 con cualquier clase y sin el requisito derivado QObject:

void WorkspaceWidget::wwShowEvent() 
{ 
    //Show event: query a reload of the saved state and geometry 
    gcmessage("wwShowEvent "+ this->title()); 
    struct{void* t; void operator()(){ static_cast<WorkspaceWidget*>(t)->wwReloadWindowState(); }}f; 
    f.t=this; 
    QObject::connect(&reloadStateTimer, &QTimer::timeout, f); 
    reloadStateTimer.start(); 
} 

void WorkspaceWidget::wwReloadWindowState() 
{ 
    gcmessage(dynamic_cast<QObject*>(this)->metaObject()->className()); 
} 

Básicamente, necesito para conectar una señal de temporizador a una clase no derivada de QObject, pero quiere pasar mt "this" correctamente.

QObject :: connect se puede conectar a la función normal en Qt 5, por lo que esta clase anónima es en realidad un funtor que mantiene el puntero en sí mismo, aún pasando la conexión de ranura.

+0

Pero es mucho mejor reemplazar con lambda en C++ 11 – paulm

+0

En el momento de escribir este artículo, QObject no entendía qué es una "Lambda", pero lo arreglaron después. –

0

También se pueden hacer cosas con automóviles en el anonimato (vs2015)

struct { 

    auto* operator->() {return this;} 
    //do other functions 

} mystruct; 
Cuestiones relacionadas