Una de las maneras más claras de determinar cuando debe utilizar la composición o la herencia es preguntando cuando será necesaria la conversión desde su nueva clase. Anteriormente, en esta capitulo, la clase Stack fue especializada utilizando la herencia. Sin embargo, los cambios en StringStack serán utilizados son como contenedores de string y nunca serán convertidos, pero ello, es mucho mas apropiado utilizas la alternativa de la composición.
//: C14:InheritStack2.cpp // Composition vs. inheritance #include "../C09/Stack4.h" #include "../require.h" #include <iostream> #include <fstream> #include <string> using namespace std; class StringStack { Stack stack; // Embed instead of inherit public: void push(string* str) { stack.push(str); } string* peek() const { return (string*)stack.peek(); } string* pop() { return (string*)stack.pop(); } }; int main() { ifstream in("InheritStack2.cpp"); assure(in, "InheritStack2.cpp"); string line; StringStack textlines; while(getline(in, line)) textlines.push(new string(line)); string* s; while((s = textlines.pop()) != 0) // No cast! cout << *s << endl; } ///:~
Listado 14.19. C14/InheritStack2.cpp
El fichero es idéntico a InheritStack.cpp, excepto que un objeto Stack es alojado en StringStack y se utilizan las funciones miembros para llamarlo. No se consume tiempo o espacio porque el subobjeto tiene el mismo tamaño y todas las comprobaciones de tipos han ocurrido en tiempo de compilación.
Sin embargo, esto tiende a confusión, podría también utilizar la herencia privada para expresar "implementado en términos de". Esto también resolvería el problema de forma adecuada. Un punto importante es cuando la herencia múltiple puede ser garantizada. En este caso, si observa un diseño en que la composición pueda utilizarse en vez de la herencia, debe eliminar la necesidad de utilizar herencia múltiple.