J'ai une classe abstraite Engine3D
et ses structures (Vector3D
, etc.) dans les fichiers d'en-tête. J'ai maintenant une implémentation pour cette classe, ConcreteEngine3D : Engine3D
. En outre, j'ai d'autres classes comme ConcreteVector3D : Vector3D
qui ont des membres supplémentaires et des méthodes qui seront utilisées à l'intérieur ConcreteEngine3D
(pour les besoins de cet exemple, disons float length
et calculateLength()
).C + + changer de type dans le constructeur?
En main.cpp J'ai le code:
#include "ConcreteEngine3D.h"
Engine3D * engine;
...
int main(){
engine = new ConcreteEngine3D();
Vector3D* vector = new Vector3D(engine, 10, 5, 2);
}
Je veux la vector
variables soient de type ConcreteVector3D*
.
je besoin de ce genre dans ConcreteEngine3D
, mais main.cpp je ne sais même pas c'est ce type et ne pas utiliser les champs étendus comme length
. En outre, je ne peux pas utiliser dans le fichier main.cpp spécifiquement de ConcreteEngine3D.h (seulement Engine3D.h) - c'est pour la flexibilité, en changeant la mise en œuvre doit seulement changer l'inclusion et la ligne avec new ConcreteEngine3D()
.
Je ne veux pas modifier ce code ci-dessus ou les en-têtes d'origine de Engine3D
.
Dans le constructeur de Vector3D
je mets toujours un pointeur vers Engine3D
objet (et je donne ici ConcreteEngine3D
type).
Peut-être que je peux faire quelque chose dans le constructeur de Vector3D
pour changer le type de celui-ci?
Par exemple appel Vector3D* Engine3D::convert(Vector3D v)
à l'intérieur du constructeur qui sera héritée de Engine3D
dans ConcreteEngine3D
(qui crée un nouvel objet ConcreteVector3D
avec des champs de Vector3D
et retourne).
Bien sûr que le code ne fonctionne pas:
Vector3D::Vector3D(Engine3D *engine){
//how to 'return' or 'convert' the type to the one that returns engine->convert(this);
}
Donc, fondamentalement, je veux obtenir l'effet code ci-dessous, mais sans la ligne vector = engine->convert(vector)
ou Vector3D* vector2 = new ConcreteVector3D(engine, 10, 5, 2)
.
#include "ConcreteEngine3D.h"
Engine3D * engine;
...
int main(){
engine = new ConcreteEngine3D();
Vector3D* vector = new Vector3D(engine, 10, 5, 2); //produces Vector3D, not ConcreteVector3D
vector = engine->convert(vector); //cannot be here! but creates the right object
Vector3D* vector2 = new ConcreteVector3D(engine, 10, 5, 2); //also creates rights object, but cannot be here!
}
Aussi, je ne veux pas utiliser l'usine dans Engine3D
ou ConcreteEngine3D
. Je veux permettre à l'utilisateur de créer Vector3D
juste comme j'ai écrit dans le premier code.
Peut-être qu'il serait préférable d'écrire un mini-programme de travail démontrant le problème. Ce n'est pas très clair ce que vous essayez d'atteindre. –
Et maintenant vous attribuez des pointeurs aux valeurs ('Vector3D vector = new Vector3D ...') qui ne devrait pas compiler. –
Vous pouvez remplacer le 'operator new' de' Vector3D' pour qu'il alloue 'sizeof (ConcreteVector3D)'. Ensuite, dans Vector3D, créez un 'ConcreteVector3D' et' memcpy (this, ...) '. Mais ce serait horrible. Vous n'allez pas aider votre utilisateur avec de telles surprises - lisez à propos du [Principe de Least Astonishment] (http://en.wikipedia.org/wiki/Principle_of_least_astonishment). Je vous suggère de reconsidérer en utilisant une usine - avoir une méthode 'Vector3D * GetVector3D()'. Définissez-le sur un fichier cpp séparé et demandez-lui de renvoyer un pointeur vers un objet 'ConcreteVector3D'. De cette façon, vous n'aurez aucune dépendance sur 'ConcreteVector3D'. – eran