Disons que j'ai une classe boîte, et un utilisateur peut créer boîtes. Comment faire? Je comprends que je crée des objets par className objectName(args);
mais comment le faire dynamiquement, en fonction de l'entrée de l'utilisateur?Comment créer des objets de classe dynamiquement?
Répondre
La méthode usine suivante crée Box
instances dynamiquement en fonction de l'entrée utilisateur:
class BoxFactory
{
public:
static Box *newBox(const std::string &description)
{
if (description == "pretty big box")
return new PrettyBigBox;
if (description == "small box")
return new SmallBox;
return 0;
}
};
Bien sûr, PrettyBigBox
et SmallBox
proviennent en effet du Box
. Jetez un oeil sur les modèles de création dans le C++ design patterns wikibook, comme l'un d'entre eux s'applique probablement à votre problème.
En C++, il est possible d'allouer des objets en utilisant le stockage automatique (pile) et dynamique (tas).
Type variable_name; // variable_name has "automatic" storage.
// it is a local variable and is created on the stack.
Type* pointer_name = NULL; // pointer_name is a "pointer". The pointer, itself,
// is a local variable just like variable_name
// and is also created on the stack. Currently it
// points to NULL.
pointer_name = new DerivedType; // (where DerivedType inherits from Type). Now
// pointer_name points to an object with
// "dynamic" storage that exists on the heap.
delete pointer_name; // The object pointed-to is deallocated.
pointer_name = NULL; // Resetting to NULL prevents dangling-pointer errors.
Vous pouvez utiliser des pointeurs et des tas d'allocation pour construire dynamiquement des objets comme dans:
#include <cstdlib>
#include <iostream>
#include <memory>
class Base {
public:
virtual ~Base(){}
virtual void printMe() const = 0;
protected:
Base(){}
};
class Alpha : public Base {
public:
Alpha() {}
virtual ~Alpha() {}
virtual void printMe() const { std::cout << "Alpha" << std::endl; }
};
class Bravo : public Base {
public:
Bravo() {}
virtual ~Bravo() {}
virtual void printMe() const { std::cout << "Bravo" << std::endl; }
};
int main(int argc, char* argv[]) {
std::auto_ptr<Base> pointer; // it is generally better to use boost::unique_ptr,
// but I'll use this in case you aren't familiar
// with Boost so you can get up and running.
std::string which;
std::cout << "Alpha or bravo?" << std::endl;
std::cin >> which;
if (which == "alpha") {
pointer.reset(new Alpha);
} else if (which == "bravo") {
pointer.reset(new Bravo);
} else {
std::cerr << "Must specify \"alpha\" or \"bravo\"" << std::endl;
std::exit(1);
}
pointer->printMe();
return 0;
}
La réponse dépend du nombre de classes différentes dont vous voulez pour créer les instances.
Si le nombre est énorme (l'application doit être capable de créer une instance de n'importe quelle classe de votre application), vous devez utiliser la fonctionnalité de réflexion de .Net. Mais, pour être honnête, je ne suis pas un grand fan de l'utilisation de la réflexion dans la logique métier, donc je conseillerais de ne pas le faire.
Je pense qu'en réalité vous avez un nombre limité de classes pour lesquelles vous voulez créer des instances. Et toutes les autres réponses font cette hypothèse. Ce dont vous avez réellement besoin, c'est d'un modèle d'usine. Dans le code suivant, je suppose aussi que les classes dont vous souhaitez créer des instances, dérivent toutes de la même classe de base, disons que des animaux, comme ceci:
class Animal {...};
class Dog : public Animal {...}
class Cat : public Animal {...}
Ensuite, créez une usine abstraite qui est une interface crée un animal:
class IFactory
{
public:
Animal *create() = 0;
};
Ensuite, créez des sous-classes pour chacun des différents types d'animaux. Par exemple. pour la classe Chien ceci deviendra ceci:
class DogFactory : public IFactory
{
public:
Dog *create() {return new Dog();}
};
Et pareil pour le chat.
La méthode DogFactory :: create écrase la méthode IFactory :: create, même si leur type de retour est différent. C'est ce que l'on appelle les types de retour co-variant. Ceci est autorisé tant que le type de retour de la méthode de la sous-classe est une sous-classe du type de retour de la classe de base.
Ce que vous pouvez faire est de cas mettre de toutes ces usines dans une carte, comme ceci:
typedef std::map<char *,IFactory *> AnimalFactories
AnimalFactories animalFactories;
animalFactories["Dog"] = new DogFactory();
animalFactories["Cat"] = new CatFactory();
Après l'entrée d'utilisateur, vous devez trouver l'usine correcte, et lui demander de créer l'instance de l'animal:
AnimalFactories::const_iterator it=animalFactories.find(userinput);
if (it!=animalFactories.end())
{
IFactory *factory = *it;
Animal *animal = factory->create();
...
}
Ceci est l'approche typique d'une usine abstraite. Il existe également d'autres approches. En m'enseignant C++ j'ai écrit un petit article de CodeProject à ce sujet. Vous pouvez le trouver ici: http://www.codeproject.com/KB/architecture/all_kinds_of_factories.aspx.
Bonne chance.
Une manière simple consiste à utiliser un vecteur. d'abord, incluez la bibliothèque de vecteurs et créez un objet temporaire en tant que classe.
class temp;
puis, faire un vecteur par exemple des objets nommés avec votre type de classe:
#include <vector>
.
.
vector <class>objects;
vous pouvez ajouter une boucle à ajouter un exemple object.for, j'ai une classe qui a nommé temp une fonction nommée entrée et je veux ajouter:
while(1){
temp.input();
objects.push_back(temp);
}
maintenant vous avez une classe dynamique. pour accéder à vos objets, vous pouvez utiliser cette façon:
objects[i];
et si vous voulez supprimer un objet, il suffit d'utiliser de cette façon: 1.Find votre position d'objet dans le vecteur. montant 2.CHANGER du dernier bloc de votre vecteur avec qui et retirez le dernier bloc:
objects[location of the object you want to remove]=objects[location of your last block];
objects.pop_back();
si vous voulez connaître l'emplacement du dernier bloc de votre vecteur faire:
int lastblock;
lastblock=(objects.size()-1);
note: vous pouvez utiliser des vecteurs comme un tableau.
- 1. IoC: Comment créer des objets dynamiquement
- 2. Comment créer des objets dynamiquement de façon élégante en python?
- 3. Comment ajouter dynamiquement des objets
- 4. Objective-C: Comment créer dynamiquement des objets GUI?
- 5. C# Comment créer des objets sans définition de classe?
- 6. comment créer dynamiquement des méthodes pour faire fonctionner sur des objets de classe initialisés lors de l'exécution
- 7. Comment créer des objets lors de l'exécution?
- 8. Comment créer correctement des objets de jeu
- 9. Comment créer des onglets Dynamiquement
- 10. Comment appeler dynamiquement des objets Json?
- 11. Créer dynamiquement des attributs de classe avec attr_accessor
- 12. Comment ajouter dynamiquement des propriétés à des objets dans C#
- 13. Comment créer dynamiquement un objet d'une classe générique?
- 14. Meilleure façon de créer dynamiquement de nouveaux objets en JavaScript?
- 15. Objets UIView créés dynamiquement
- 16. dynamiquement décorer des objets dans C#
- 17. créer des composants dynamiquement
- 18. Comment créer une classe dans un fichier dbml dynamiquement
- 19. Comment créer dynamiquement des fonctions de niveau module à partir des méthodes d'une classe
- 20. Comment créer des rectangles dans WPF dynamiquement?
- 21. Django: comment créer des sites dynamiquement?
- 22. jqgrid comment créer dynamiquement des colonnes
- 23. Comment dimensionner dynamiquement des objets HTMLAREA dans PeopleTools 8.50?
- 24. Comment puis-je créer dynamiquement une instance d'une classe?
- 25. comment créer dynamiquement une instance d'une classe en python?
- 26. Créer une instance de classe COM dynamiquement dans .NET
- 27. créer des objets déplaçables iPhone
- 28. Mootools: créer dynamiquement des liens de pagination
- 29. GridView Créer des champs dynamiquement
- 30. Comment obtenir dynamiquement des noms de classe de plugin Pagination?
Pouvez-vous donner un exemple de code (potentiellement pseudocode)? –
Créez-les où? Vous pouvez les stocker dans un 'std :: vector', par exemple, mais cela dépend vraiment de ce que vous faites. – GManNickG
Malheureusement, en C++, vous ne pouvez pas appeler dynamiquement un constructeur. Le seul moyen est de stocker des objets qui sont capables de retourner un objet construit frais de ce que vous voulez à l'exécution. Les exemples de réponses que vous avez déjà reçus sont tout à fait pertinents. –