Nehmen wir an, ich habe eine Klasse Box, und ein Benutzer kann Boxen erstellen. Wie es geht? Ich verstehe, dass ich Objekte von className objectName(args);
erstellen, aber wie es dynamisch zu tun, abhängig von der Benutzereingabe?Wie erstellt man Klassenobjekte dynamisch?
Antwort
Die folgende Factory-Methode erstellt Box
Instanzen auf Benutzereingaben dynamisch basierend:
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;
}
};
Natürlich PrettyBigBox
und SmallBox
ableiten beide aus Box
. Werfen Sie einen Blick auf die kreativen Muster in der C++ design patterns wikibook, wie einer von ihnen wahrscheinlich auf Ihr Problem zutrifft.
In C++ ist es möglich, Objekte mit automatischen (Stapel) und dynamischen (Heap) Speicher zuzuweisen.
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.
Sie können mit Zeiger und Heap-Zuweisung dynamisch Objekte konstruieren, wie in:
#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;
}
Verwandte: the "Factory" object-oriented design pattern
Die richtige Antwort ist abhängig von der Anzahl der verschiedenen Klassen, von denen Sie wollen um die Instanzen zu erstellen.
Wenn die Anzahl sehr groß ist (die Anwendung sollte in der Lage sein, eine Instanz einer beliebigen Klasse in Ihrer Anwendung zu erstellen), sollten Sie die Reflexionsfunktion von .Net verwenden. Aber um ehrlich zu sein, ich bin kein großer Fan der Reflexion in der Geschäftslogik, also rate ich dazu, dies nicht zu tun.
Ich denke, dass Sie in Wirklichkeit eine begrenzte Anzahl an Klassen haben, für die Sie Instanzen erstellen möchten. Und alle anderen Antworten machen diese Annahme. Was Sie wirklich brauchen, ist ein Fabrikmuster. Im nächsten Code gehe ich davon aus, dass die Klassen, von denen Sie Instanzen erstellen möchten, werden alle von der gleichen Basisklasse ableiten, lassen Sie uns Tier sagen, wie folgt aus:
class Animal {...};
class Dog : public Animal {...}
class Cat : public Animal {...}
Dann ein abstraktes Werk schaffen, das ist eine Schnittstelle, Erzeugt ein Tier:
class IFactory
{
public:
Animal *create() = 0;
};
Dann erstellen Unterklassen für jede der verschiedenen Arten von Tieren. Z.B. für die Hundeklasse wird dies so:
class DogFactory : public IFactory
{
public:
Dog *create() {return new Dog();}
};
Und das gleiche für die Katze.
Die DogFactory :: create-Methode überschreibt die IFactory :: create-Methode, auch wenn ihr Rückgabetyp unterschiedlich ist. Dies nennt man co-variante Rückgabetypen. Dies ist zulässig, solange der Rückgabetyp der Methode der Unterklasse eine Unterklasse des Rückgabetyps der Basisklasse ist.
Was Sie jetzt tun können, ist Instanzen all diese Fabriken in eine Karte setzen, wie folgt aus:
typedef std::map<char *,IFactory *> AnimalFactories
AnimalFactories animalFactories;
animalFactories["Dog"] = new DogFactory();
animalFactories["Cat"] = new CatFactory();
Nach der Benutzereingabe, müssen Sie die richtige Fabrik zu finden, und sie auffordern, die Instanz zu erstellen des Tieres:
AnimalFactories::const_iterator it=animalFactories.find(userinput);
if (it!=animalFactories.end())
{
IFactory *factory = *it;
Animal *animal = factory->create();
...
}
Dies ist der typische abstrakte Fabrikansatz. Es gibt auch andere Ansätze. Als ich C++ selbst unterrichtete, schrieb ich einen kleinen CodeProject-Artikel darüber. Sie können es hier finden: http://www.codeproject.com/KB/architecture/all_kinds_of_factories.aspx.
Viel Glück.
Ein einfacher Weg ist, Vektor zu verwenden. Als erstes fügen Sie die Vektorbibliothek hinzu und erstellen Sie ein temporäres Objekt als Ihre Klasse.
class temp;
dann einen Vektor zum Beispiel benannte Objekte mit Ihrer Klasse Art machen:
#include <vector>
.
.
vector <class>objects;
dann Sie eine Schleife zu Hinzufügen eines object.for Beispiels hinzufügen können, habe ich eine Klasse mit dem Namen Temp, der hat eine Funktion namens Eingang und ich möchte hinzufügen:
while(1){
temp.input();
objects.push_back(temp);
}
jetzt haben Sie eine dynamische Klasse. auf Ihre Objekte zugreifen, die Sie auf diese Weise verwenden können:
objects[i];
und wenn Sie ein Objekt löschen möchten, einfach auf diese Weise verwenden: 1.Suchen Ihr Objekt Lage im Vektor. 2.Ändern Menge des letzten Blocks des Vektors mit, dass und entfernen Sie den letzten Block:
int lastblock;
lastblock=(objects.size()-1);
:
objects[location of the object you want to remove]=objects[location of your last block];
objects.pop_back();
wenn Sie den Speicherort des letzten Blocks des Vektors tun dies wissen wollen
Hinweis: Sie können Vektoren wie ein Array verwenden.
- 1. Wie erstellt man mehrere Klassenobjekte mit einer Schleife in Python?
- 2. Wie erstellt man Mungoschema dynamisch?
- 3. Wie erstellt man Threads dynamisch?
- 4. Wie kann man Klassenobjekte entfernen?
- 5. Wie erstellt man eine WMI-Eigenschaft dynamisch?
- 6. Wie erstellt man dynamisch eine Umgebungsvariable?
- 7. Wie erstellt man Registerkarten in extjs dynamisch?
- 8. Wie man ein Dropdown-Menü dynamisch erstellt?
- 9. Wie man Button in Android dynamisch erstellt?
- 10. Wie behandelt man Klassenobjekte mit zirkulären Referenzen?
- 11. Wie erstellt man eine Metaklasse?
- 12. Klassenobjekte vergleichen
- 13. C# Klassenobjekte
- 14. Klassenobjekte in C++
- 15. wie dynamisch erstellt SQLAlchemy Spalten
- 16. Wie erstellt man dynamisch eine Instanz einer Klasse in Python?
- 17. Wie erstellt man dynamisch einen Datensatz für Flot JS?
- 18. Wie man Bootstrap Modals dynamisch als Angular2 Komponenten erstellt?
- 19. Wie man ein Array von Funktionen dynamisch erstellt?
- 20. T-SQL Wie erstellt man Tabellen dynamisch in gespeicherten Prozeduren?
- 21. Wie erstellt man Radio Buttons dynamisch in swift?
- 22. Wie erstellt man eine HTML-Eingabe dynamisch mit jQuery?
- 23. Wie erstellt man dynamisch eine Tabelle aus einem JSON-Array?
- 24. wie man uitextfield dynamisch mit der for-Schleife erstellt
- 25. Wie erstellt man eine Instanz eines Objekts in StructureMap dynamisch?
- 26. Wie erstellt man UIImageViews dynamisch/unbegrenzt basierend auf dynamischem Bedarf?
- 27. Wie erstellt man das Jpa-Repository dynamisch innerhalb einer Klasse?
- 28. MySQL: Wie man Tabelle dynamisch in der gespeicherten Prozedur erstellt?
- 29. Dynamisch erstellt Regex Java
- 30. Typoskript, Klassenobjekte serialisieren
Können Sie ein (möglicherweise Pseudocode) Code Beispiel geben? –
Erstelle sie wo? Sie können sie zum Beispiel in einem 'std :: vector' speichern, aber das hängt wirklich davon ab, was Sie tun. – GManNickG
Leider in C++ können Sie einen Konstruktor nicht dynamisch aufrufen. Die einzige Möglichkeit besteht darin, Objekte zu speichern, die zur Laufzeit ein neu konstruiertes Objekt zurückgeben können. Die Beispiele, die Sie bereits erhalten haben, sind vollständig relevant. –