problema con virtuales puras

03/09/2003 - 17:15 por Manuel D. Jiménez | Informe spam
Hola,

Hoy, nuestra duda es de C++. Voy al grano:

class CParent {
public:
void Run ();
private:
virtual void _ConcreteRun () = 0; // virtual pura
};

void CParent::Run ()
{
// some code...

_ConcreteRun();
}

class CChild : public CParent {
private:
void _ConcreteRun ();
};

void CChild::_ConcreteRun()
{
// some code...
}

Si hacemos:

CChild myChild;
myChild.Run();

Esté método run produce una excepción porque llama a la función _ConcreteRun
de CParent, que es virtual pura (por lo tanto, no existe).

¿Qué estamos haciendo mal? ¿Cómo hacemos para que se llame a
CChild::_ConcreteRun ?

Preguntas similare

Leer las respuestas

#1 Manuel D. Jiménez
03/09/2003 - 18:07 | Informe spam
Ya lo hemos descubierto:

Tenemos un constructor...

CParent::CParent(LPCTSTR str)
{
Run(str);
}

void CParent::Run(LPCTSTR str)
{
_ConcreteRun(str);
}

... y...

CChild::CChild(LPCTSTR str) : CParent(str)
{
}



Después tenemos el código:

std::string str;
CChild myChild;

myChild = str.c_str();

Esta línea debería darnos error de compilación, porque no hemos sobrecargado
el operador =. Sin embargo, el compilador se lo traga, y lo que hace es
llamar al constructor de CParent con str.c_str() como parámetro, lo cual
termina llamando a la versión virtual pura (!!!) de _ConcreteRun().

En fin, el error está solucionado, pero si alguien no lo sigue viendo
extraño que nos lo diga.

Gracias.


"Manuel D. Jiménez" escribió en el mensaje
news:
Hola,

Hoy, nuestra duda es de C++. Voy al grano:

class CParent {
public:
void Run ();
private:
virtual void _ConcreteRun () = 0; // virtual pura
};

void CParent::Run ()
{
// some code...

_ConcreteRun();
}

class CChild : public CParent {
private:
void _ConcreteRun ();
};

void CChild::_ConcreteRun()
{
// some code...
}

Si hacemos:

CChild myChild;
myChild.Run();

Esté método run produce una excepción porque llama a la función


_ConcreteRun
de CParent, que es virtual pura (por lo tanto, no existe).

¿Qué estamos haciendo mal? ¿Cómo hacemos para que se llame a
CChild::_ConcreteRun ?
Respuesta Responder a este mensaje
#2 Rodrigo Corral González
03/09/2003 - 18:31 | Informe spam
Solo una aclaración...

Dices que la linea myChild = str.c_str(); deberia dar un error pero eso
no es cierto. Esa linea hace exactamente lo que tiene que hacer. Si
quiere evita que el constructor se use para conversiones implicitas y
asignaciones marcalo con el modificador explicit.

Un saludo
Rodrigo Corral González
Respuesta Responder a este mensaje
#3 Manuel D. Jiménez
04/09/2003 - 08:57 | Informe spam
Es curioso como, después de muchos años, descubre uno que aún no lo sabe
todo de C++.

Muchas gracias.

"Rodrigo Corral González" escribió en el mensaje
news:
Solo una aclaración...

Dices que la linea myChild = str.c_str(); deberia dar un error pero eso
no es cierto. Esa linea hace exactamente lo que tiene que hacer. Si
quiere evita que el constructor se use para conversiones implicitas y
asignaciones marcalo con el modificador explicit.

Un saludo
Rodrigo Corral González
Respuesta Responder a este mensaje
#4 christian salazar
06/09/2003 - 02:48 | Informe spam
bueno, saludos primeramente

mi pregunta es, para q la declaras virtual pura ?
yo la hubiese dejado no pura, y simplemente con codigo
nulo,
asi:
class CParent {
public:
void Run ();
private:
virtual void _ConcreteRun () {};

};

la necesida de ser virtual pura radica en la optimizacion
de espacio en memoria para que no se generen un monton ed
funciones nulas en el caso que tengas una herencia muy
grande, por favor no me digas que estas haciendo una clase
de herencia muy profunda!!! tenemos memria de sobra mal
utilizada, un par de bytes de mas no matan a nadie (o si?)

chao, espero ayudarte.
Respuesta Responder a este mensaje
#5 Rodrigo Corral González
09/09/2003 - 15:44 | Informe spam
No solo se trata de un tema de consumo de memoria. El hacer la función
virtual pura, impone un contrato a todos los que deriven de ella: deben
implemetar el método. Si la fución no es virtual pura ese contrato no
existe.

En genera se puede decir que proveer una fución sin código en una clase
base es un mal diseño.

Un saludo
Rodrigo Corral González
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida