2012-04-02 23 views
6

Soy bastante nuevo en C++, pero me encontré con un problema que parece que no puedo resolver. Utilizaré automóviles para ilustrar el problema, solo para facilitar las cosas. Bien, digamos que tengo un auto de clase base y tengo diferentes marcas que heredan de esa clase. Como tal:Función derivada de llamada de C++ desde la instancia de clase base

class Car 
{ 
    public: 
     Car(); 
}; 

class Ford: public Car 
{ 
    public: 
     Ford(); 
     void drive(); 
     void park(); 
}; 

La idea es juntar todos estos diferentes coches en un solo vector del tipo Coche. Como lo siguiente:

vector<Car*> cars; 
cars.push_back(new Ford()); 
cars.back()->drive(); //this won't work 

¿Cómo puedo llamar a la función derivada en la instancia de la clase base? Tenga en cuenta que quiero colocar todo esto en un solo vector. La razón detrás de esto es porque solo quiero usar la última instancia derivada de clase de automóvil que se ha agregado. (En este caso, la clase de vehículo derivada es ford). También tenga en cuenta que todas las clases de automóviles tendrán las mismas funciones.

Respuesta

7

Si estas funciones son realmente comunes para todas las clases derivadas, entonces tiene una interfaz común, por lo que debe expresar esto a través de la clase base. Para ello, se declara estas funciones tan pura-virtual:

class Car { 
public: 
    virtual void drive() = 0; // Pure-virtual function 
}; 

class Ford : public Car { 
public: 
    virtual void drive() { std::cout << "driving Ford\n"; } 
}; 

... 

vector<Car*> cars; 
cars.push_back(new Ford()); 
cars.back()->drive(); //this will work 

[En una nota lateral, generalmente se considera una mala práctica de tener un vector de punteros primas, ya que hace que la gestión de memoria complicado. Debería considerar el uso de punteros inteligentes.]

+0

muchas gracias por la respuesta excelente y rápido, esto hizo el truco. – Dan

2

Si todos Car clases tienen las mismas funciones y luego declaran como pura virtual en la clase base Car:

class Car 
{ 
public: 
    Car(); 
    virtual ~Car(); 
    virtual void drive() = 0; 
    virtual void park() = 0; 
}; 

Esto permitirá que el código de ejemplo que utiliza vector trabajar como publicado.

0

Puede ser, si es posible se puede definir como clase base

class Car 
{ 
    public: 
     Car(); 
     virtual void drive(); 
}; 
0

Usted tiene que definir la interfaz como:

class Car{ 
public: 
Car(); 
virtual void moveForward(unsigned int speed) = 0; 
virtual void moveBack(unsigned int speed) = 0; 
//... 
virtual ~Car(); 
}; 

No se olvide de hacer el destructor virtual. Después de eso, solo necesita implementar estos métodos en sus clases secundarias y llamarlos después. También en vector puede usar shared_ptr o simplemente pasar las instancias directamente.

3

Tiene dos opciones: o bien poner un método de unidad virtual() en la definición de su automóvil, o enviar los punteros del coche a los punteros de Ford. Lo más probable es que quieras hacer lo primero.

class Car 
{ 
    public: 
     Car(); 
     virtual void drive() { // default implementation} 
}; 

¡Ahora puede conducir() su automóvil! También puede hacer que la unidad() una función virtual pura, así:

class Car 
{ 
    public: 
     Car(); 
     virtual void drive() = 0; 
}; 

Esto básicamente significa que no hay una aplicación por defecto para la unidad(): Debe ser reimplantado en una subclase.La segunda forma en que he mencionado, que, de nuevo, es probable que no quiera, pero debe ser incluido por la totalidad, ha de emitir el puntero:

static_cast<Ford*>(cars.back())->drive(); 

Esto sólo funciona si usted sabe de antemano que el coche es un Ford , sin embargo, y no es de mucha utilidad en este escenario. También puede consultar dynamic_cast.

+0

Sí, usaré el primer método, pero es bueno saber que existe otra forma. Gracias por la info! – Dan

+0

@Anthony, creo que para el segundo método sería mejor usar un dyanamic_cast en lugar de un static_cast – exs

0

Debe poner una función virtual.

Una función virtual en la clase base. Se puede implementar una función virtual en la subclase, por lo que puede especializar el comportamiento de la unidad(), por ejemplo.

puede encontrar un FAQ (o tutorial) acerca de las funciones virtuales aquí:

http://www.parashift.com/c++-faq-lite/virtual-functions.html

Cuestiones relacionadas