2016-04-21 3 views
0

Ist es nützlich, einen Zeiger oder ein Array von Zeigern auf dem Heap zu erstellen? Wenn ja, wann und warum müsste ich das tun?Ist es nützlich, Zeiger auf dem Heap zu erstellen?

Zum Beispiel:

#include <iostream> 

class Box { /* things... */ }; 

int main(void){ 

    // Single pointer on the heap 
    Box** pBox = new Box*(nullptr); 
    *pBox = new Box(); 

    // Array of pointers on the heap 
    Box** pBoxes = new Box*[3]{}; 
    pBoxes[0] = new Box(); 
    pBoxes[1] = new Box(); 
    pBoxes[2] = new Box(); 

    // Delete pointers... 

    return 0; 
} 

EDIT: Nur meine Frage klarer zu machen ... Ich weiß, mit rohen Zeigern zu tun ist nicht die beste Praxis ... Ich will nur voll Zeiger und ihre Verwendungen zu verstehen Da sie ein wichtiger Teil von C++ sind, ist meine Frage (ist es nützlich ...).

+7

Wenn Sie einem Gentlemen's Java Club beitreten, müssen Sie möglicherweise einen Code wie diesen schreiben, wenn Sie vermeiden möchten, dass Sie schikaniert werden. –

+0

@KerrekSB, und die logische Fortsetzung ist - aber das wäre der einzige Grund, dies zu tun. – SergeyA

+0

Wenn ein Objekt Zeigerelemente hat und Sie das Objekt auf dem Heap erstellen, haben Sie automatisch Zeiger auf den Heap .... – alain

Antwort

3

Der Grund für die Zuweisung von Speicherbereich auf dem Heap oder Stack ist nicht mit dem Typ der zugewiesenen Variablen verbunden, sondern hängt davon ab, wie er zugewiesen ist und wie er verwendet werden soll.

In jedem Fall sollten Sie heute normalerweise new Anweisungen vermeiden und "verwaltete" Zeiger verwenden, insbesondere die std::xxx Varianten.

+1

Ich kenne intelligente Zeiger ... aber als Zeiger sind sehr wichtiger Teil von C++ ... Ich will sie nur vollständig verstehen, auch wenn es besser ist, rohe Zeiger zu vermeiden – Laith

+0

Ein weiterer Grund ist die Lebensdauer der Variablen. Eine im dynamischen Speicher deklarierte Variable kann die Ausführung einer Funktion überleben. –

+0

@ThomasMatthews das ist meistens, was ich mit "* wie es gemeint ist, um verwendet zu werden * gemeint". – Amit

2

Von dem, was ich lese, hat der Heap langsamer Zugriffsgeschwindigkeit als der Stapel, also glaube ich nicht, dass es sehr nützlich ist, zu tun, worüber Sie sprechen. Vielleicht hilft Ihnen dies Ihre Forschung: http://gribblelab.org/CBootcamp/7_Memory_Stack_vs_Heap.html

+0

Um klar zu sein, ist die * Zuweisung * einer Variablen aus dem Heap (dynamischer Speicher) langsamer als die Zuweisung aus dem Stapel. Die Zugriffsgeschwindigkeit sollte gleich sein. –

0

Ja, es kann Gründe geben, Zeiger auf dem Haufen zu haben. Eine Fabrik-Funktion, die der Überblick über jedes Objekt hält er sich in einem Vektor, zum Beispiel könnte speichern erstellt:

vector<unique_ptr<Box>> BoxFactory::allBoxes; 

Box* BoxFactory::makeBox() 
{ 
    allBoxes.emplace_back(make_unique<Box>()); 
    return allBoxes.back().get(); 
} 

Hinweis: einige Leute haben vorgeschlagen, dass dies nicht doppelt indirection. Es ist:

Genau wie beim Beispiel des OP haben Sie zwei Zeiger im Spiel, nicht nur einen. Der Vektor enthält Zeiger, die auf dem Heap zugeordnet wurden, und diese Zeiger enthalten einen anderen Zeiger, der auf das Box-Objekt zeigt.

+0

Dies ist eine 'Box', keine' Box * '. – Barry

+0

@Barry 'unique_ptr' weist eine' Box' zu. Der Vektor weist Zeiger zu (hier in "unique_ptr" eingewickelt). Der Vektor enthält also Zeiger auf den Heap, und diese Zeiger zeigen auf Boxen. –

+0

Das OP-Konzept ist ein Zeiger auf einen Zeiger; doppelte Indirektion. Möglich, nicht sehr effizient. –

2

Wie eine andere Antwort erwähnt, in der Regel ist der tatsächliche Zugriff auf den Heap langsamer als der Zugriff auf den Stapel, jedoch ist die Zugriffsgeschwindigkeit im Allgemeinen nicht der Grund für die Erstellung und Umgang mit Zeigern.

Der typische Anwendungsfall für Zeiger besteht darin, das Kopieren von Daten zu vermeiden. Wenn Sie mit großen Objekten arbeiten und diese zwischen vielen Funktionen übergeben, wird es als "besser" angesehen, dass sie als Referenz und nicht als Wert übergeben werden.

Wenn Sie das Objekt aus dem Stapel verwenden (es sei denn, Sie übergeben es als Referenz, aber es gibt Einschränkungen dabei), erstellt es eine Kopie der gesamten Sache für die aufgerufene Methode. Wenn Sie einen Zeiger auf eine Methode übergeben, wird nur eine Adresse kopiert.

Sehen Sie, wenn this article hilft Ihnen, die Unterschiede zu verstehen.

Verwandte Themen