2012-01-29 9 views
5

que no se sabe muy bien cómo describir esto, pero este es el código:¿Cómo se puede derivar una clase de una plantilla especializada en sí misma?

class A : public std::vector<A> 
{ 
}; 

//.... 

A a; 
a.push_back(a); 

qué hace y por qué hacer esto?

Respuesta

4

Esto es curiously recurring template pattern(CRTP).
Le permite implementar polimorfismo estático.

Sin embargo, es una mala práctica usar std::vector como clase base porque no tiene un destructor virtual.

+0

Acabo de usar el vector porque no quería crear una clase de plantilla solo para demostrar un punto :). Pero estás en lo correcto. Lo investigaré. Gracias –

0

La subclase es para finalizar los genéricos. El vector solo puede contener objetos del tipo A, no vectores arbitrarios.

Ahora, ¿por qué está construyendo un objeto que contiene lo que hago no saber. Pero hay razones para hacerlo. Por ejemplo, para pruebas unitarias, para garantizar que un algoritmo pueda manejar colecciones que contienen bucles. Un algoritmo ingenuo probablemente se ejecutará en un bucle infinito, por lo que no pasará la prueba unitaria.

1

Dado que es un vector de A sy no de A* s, a no puede contenerse per se. Pero ese push_back agregará al vector una copia de a en el momento de la llamada.

Ejemplo:

#include <vector> 
#include <iostream> 
using namespace std; 
class A : public std::vector<A> 
{ 
    public: 
     void print(int level=0){ 
      for (int i=0;i<level;i++) cout<<" "; 
      cout << "0x" << hex << (unsigned int)this << "=["; 
      if (size()){ 
       cout << endl; 
       for (int i=0; i<size(); i++) 
        (*this)[i].print(level+1); 
       for (int i=0;i<level;i++) cout<<" "; 
      } 
      cout <<"]"<<endl; 
      if(!level) cout << endl; 
     } 

}; 

int main(){ 
    A a; 
    for (int i=1;i<=3;i++){ 
     a.push_back(a); 
     a.print(); 
    } 
    return 0; 
} 

Y la salida:

0xbff4fa20=[ 
    0x9ec2008=[] 
] 

0xbff4fa20=[ 
    0x9ec2018=[] 
    0x9ec2024=[ 
    0x9ec2038=[] 
    ] 
] 

0xbff4fa20=[ 
    0x9ec2048=[] 
    0x9ec2054=[ 
    0x9ec20a0=[] 
    ] 
    0x9ec2060=[ 
    0x9ec2080=[] 
    0x9ec208c=[ 
     0x9ec2008=[] 
    ] 
    ] 
] 
Cuestiones relacionadas