2009-09-28 24 views
17

estoy tratando de hacer lo siguiente:¿Puede una clase anidada de C++ heredar su clase adjunta?

class Animal 
{ 
    class Bear : public Animal 
    { 
     // … 
    }; 

    class Giraffe : public Animal 
    { 
     // … 
    }; 
}; 

... pero mi compilador parece ahogarse con esto. ¿Es este C++ legal, y si no, hay una mejor manera de lograr lo mismo? Básicamente, quiero crear un esquema de nombres de clase más limpio. (No quiero derivar Animal y las clases internas de una clase base común)

+2

Para empezar, es necesario seguir las llaves de cierre con punto y coma después de una declaración de la clase. –

+0

No tengo claro por qué querrías hacer esto. Si entiendo correctamente, la clase Oso tendrá una clase Oso dentro de ella, lo cual ... parece un poco extraño. –

Respuesta

37

Puede hacer lo que quiera, pero debe retrasar la definición de las clases anidadas.

class Animal 
{ 
    class Bear; 
    class Giraffe; 
}; 

class Animal::Bear : public Animal {}; 

class Animal::Giraffe : public Animal {}; 
2

Realmente no responde la pregunta, pero creo que está haciendo un uso indebido de la clase anidada, tal vez debería echarle un vistazo a espacios de nombres (por cierto, la respuesta es "no es posible, porque Animal es un tipo incompleto").

15

El tipo de clase se considera incompleto hasta que se alcanza el final de su definición. No puede heredar de la clase incompleta, por lo que no puede heredar de la clase adjunta.

EDIT: Corrección
Como Richard Wolf me corrigió: Es posible heredar de clase que lo contiene si se demora la definición de las clases anidadas. Vea su respuesta para más detalles.

+1

Es posible al avanzar declarar la clase contenida. –

+1

No sabía que se permite definir una clase anidada fuera de la clase adjunta. Pero lo intenté y, sorprendentemente para mí, funciona. –

+0

@tkopec, ¿por qué no edita su respuesta para corregir su estado de cuenta? Le devolvería sus dos puntos, y yo a mi. Lo encuentro raro, especialmente porque * sabes * que está mal, ahora. –

2

No estoy seguro de lo que está tratando de lograr aquí, pero puede obtenerlo a través de espacios de nombres.

namespace creatures 
{ 

class Animal 
{ 
}; 

class Bear : public Animal 
{ 
}; 

class Giraffe : public Animal 
{ 
}; 


} 

Esto declara oso y jirafa como tipos de animales, pero pone todo el asunto en un espacio de nombres si usted está buscando para la clase base para no contaminar el espacio de nombres global.

0

Siempre vale la pena considerar el método ATL de "Herencia invertida". Me duele la cabeza cada vez que necesito hacer esto, pero la eficiencia del código objeto que obtienes es inmejorable. En algún lugar recorté el artículo de Jim Beveridge, que fue la mejor explicación que vi, pero hoy es difícil de encontrar, solo veo una referencia.

"25 mar 2004 ... Un excelente artículo de Jim Beveridge: ATL y la herencia al revés .."

+0

El artículo se ha ido al cielo, pero se puede acceder por cortesía de archive.org en http://web.archive.org/web/20070805214320/http://apostate.com/programming/atlupsidedown.html. – ndkrempel

Cuestiones relacionadas