Ich habe einen Hintergrund in C und versuche, C++ - Klassen zu verstehen und wie die Destruktoren als Objekte aufgerufen werden, die den Bereich verlassen. Als Randbemerkung würde ich angesichts der Art dessen, was ich versuche, lieber keine STL-Strukturen wie std :: array <> oder std :: vector <> für die Datencontainer verwenden, die ich unten präsentiere.Stapel- und Heapzuweisungen von instanziierten Objekten C++
Hier ist ein Überblick auf hoher Ebene meines Verständnisses. Gegeben eine Klasse:
class some_class{
public:
int * member;
size_t n_members;
some_class(size_t count) ...
~some_class() ...
// a member function or operator overload
// that returns an instance of some_class
some_class do_something()
}
...
some_class * container;
// Some scope
{
some_class foo = some_class();
some_class * bar = new some_class();
container[0] = bar;
}
Wenn some_class foo
den Umfang verlässt, wird der Destruktor aufgerufen. Wenn ich einen Zeiger auf eine Instanz some_class
in container
außerhalb des Bereichs speichern wollte, muss ich some_class bar
auf dem Heap instanziieren, so dass Speicher nicht sofort beim Verlassen des Bereichs freigegeben wird - genau wie ich in C.
Jetzt ist der Zweck von some_class
, eine beliebig große Menge von Daten zu halten, und so int * member
benötigt auf dem Heap zugeordnet werden.
oben gegeben, den Konstruktor und Destruktor für some_class() so etwas wie folgt aussehen:
// some_class constructor
some_class::some_class(size_t count) : n_members(count){
member = new int[count];
}
// some_class destructor
some_class::~some_class(){
delete[] member;
}
Nun mein Problem deutlich: Wenn ich brauche eine Instanz hinzufügen von some_class
aus der do_something()
Methode zurückgegeben, ich garantiert werde einen Speicherfehler haben (in diesem Fall eine Doppelfrei), weil do_something()
gibt einen Stapel zugewiesene some_class
:
some_class * container = new some_class[n];
// Some scope
{
some_class foo = some_class();
some_class bar = foo.do_something();
container[0] = &bar; // <-- I know this is stupid but that's the point of this question
}
delete[] container;
Mein Weg, um dies istzu machengibt einen Zeiger auf eine Instanz von some_class
zurück. Natürlich keine Lösung. Wie würde man eine solche Situation in echter C++ - Art richtig angehen?
Zum Beispiel, eine Sache, die ich gelesen habe, war die Verwendung von geteilten Zeigern oder eindeutigen Zeigern (oder Smart-Zeigern im Allgemeinen). Mein Verständnis ist jedoch, dass die Verwendung dieser Zeiger erfordert, dass Sie Ihr Objekt im Heap instanziiert haben. Es hilft auch nicht das ganze Problem über foo.do_something()
, um einen Zeiger zurückgeben.
Wie auch immer, irgendwelche Gedanken würden geschätzt werden.
* Wenn ich eine Instanz von some_class aus dem do_something() -Methode zurück hinzufügen müssen, ich garantiert bin einen Speicherfehler haben * Ja.Siehe [Die Dreiregel] (http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three), um das zu beheben. –
Und dann: http://stackoverflow.com/questions/4782757/rule-of-three-becomes-rule-of-five-with-c11/4782927#4782927 –
'Als eine Randnotiz, angesichts der Art von dem, was ich versuche ich zu tun, würde ich lieber keine STL-Strukturen verwenden. Wenn Sie kein C++ - Experte sind, können Sie unter einem Missverständnis leiden, dass wir korrigieren können. –