2012-02-14 10 views
23

Digamos que tenemos una clase base abstracta IBase con métodos virtuales puros (una interfaz).¿Es posible pasar clases derivadas por referencia a una función que toma la clase base como un parámetro

Luego derivamos CFoo, CFoo2 de la clase base.

Y tenemos una función que sabe cómo trabajar con IBase.

Foo(IBase *input); 

El escenario habitual en estos casos es la siguiente: la gestión

IBase *ptr = static_cast<IBase*>(new CFoo("abc")); 
Foo(ptr); 
delete ptr; 

Pero puntero es mejor que debe evitarse, por lo que hay una manera de utilizar las referencias en este escenario?

CFoo inst("abc"); 
Foo(inst); 

donde Foo es:

Foo(IBase &input); 
+2

Sí, lo que tienes en tu pregunta es ideal. – ildjarn

+28

Sí; el polimorfismo funciona tanto para punteros como para referencias. Y deja de lanzar, por favor. No estamos en Hollywood. –

Respuesta

39

Sí. No tiene que actualizar sus objetos. Todas las referencias/punteros a los tipos derivados se convierten implícitamente a referencias/punteros de objetos base cuando es necesario.

Así:

IBase* ptr = new CFoo("abc"); // good 
CFoo* ptr2 = static_cast<CFoo*>(ptr); // good 
CFoo* ptr3 = ptr; // compile error 

CFoo instance("abc"); 
IBase& ref = instance; // good 
CFoo& ref2 = static_cast<CFoo&>(ref); // good 
CFoo& ref3 = ref; // compile error 

Cuando tenga que abatido es posible que desee considerar el uso de dynamic_cast, si los tipos son polimórficos.

+0

Encontré dónde estaba mi problema. Estaba usando 'Foo (CFoo (" abc "));' que no estaba compilando. – Coder

+3

@Coder: en caso de que no lo sepa, la razón por la cual es un problema es porque está pasando 'Foo' como valor, y los valores no se pueden unir a las referencias lvalue no const (es decir, si' Foo' era 'Foo (IBase const & input); 'en cambio, se habría compilado). – ildjarn

0

Puede lanzar un objeto igual que un puntero. Recuerdo que esto era común al convertir char a unsigned char y varios otros modelos de cambio de signo en los días de antaño.

Cuestiones relacionadas