2009-03-17 6 views
5

Ich habe eine Klasse, die ein Objekt innerhalb einer öffentlichen Methode erstellt. Das Objekt ist privat und für die Benutzer der Klasse nicht sichtbar. Diese Methode ruft dann andere privaten Methoden innerhalb der gleichen Klasse und übergeben Sie das erstellte Objekt als Parameter:Übergeben eines intelligenten Zeigers als Argument in einer Klasse: scoped_ptr oder shared_ptr?

class Foo { 
    ... 
}; 

class A { 
    private: 
     typedef scoped_ptr<Foo> FooPtr; 

     void privateMethod1(FooPtr fooObj); 

    public: 
     void showSomethingOnTheScreen() { 
      FooPtr fooObj(new Foo); 
      privateMethod1(fooObj); 
     }; 
}; 

ich die richtige Smart-Pointer in diesem Fall glauben, wäre ein scoped_ptr sein, jedoch kann ich nicht tun dies, weil scoped_ptr macht die nicht kopierbar Klasse, wenn auf diese Weise verwendet wird, so sollte ich die Methoden wie diese machen:

void privateMethod1(FooPtr& fooObj); 

privateMethod1 speichert nicht das Objekt, weder hält Referenzen davon. Ruft nur Daten aus der Klasse Foo ab.

Der richtige Weg würde wahrscheinlich überhaupt keinen intelligenten Zeiger verwenden und das Objekt im Stapel zuweisen, aber das ist nicht möglich, weil es eine Bibliothek verwendet, die Objekte auf dem Stapel nicht erlaubt, sie müssen auf dem Heap sein .

Schließlich bin ich immer noch verwirrt über die tatsächliche Verwendung von scoped_ptr.

+1

Ich bin neugierig auf die Bibliothek, die 'Objekte auf dem Stapel nicht zulassen'. Sind Objekte, die in der Bibliothek auf dem Heap mit einer Factory zugeordnet sind? Übernimmt die Bibliothek den Zeiger und löscht ihn?Aus welchen Gründen können Sie Stack zugeordnete Objekte nicht verwenden? –

Antwort

1

Verwenden Sie hier einfach std :: auto_ptr, da Sie keine Objekte auf dem Stapel erstellen können. Und es ist besser, Ihre private Funktion einfach nur rohe Zeiger zu akzeptieren.

Wirkliche Verwendung ist, dass Sie nicht alle möglichen Ausnahmen abfangen und manuell löschen müssen.

In der Tat, wenn Ihr Ziel ist es ändert nicht Objekt und Ihr API Rückgabeobjekt sicher ist besser,

void privateMethod1(const Foo& fooObj); 

zu verwenden und das Objekt dort passieren, wie

privateMethod1(*fooObj.get()); 
+0

Das Ende ist genau dasselbe wie mit dem scoped_ptr, nur dass es Sie nicht zwingt, Ihre Methodenparameter als Referenzen zu deklarieren. Aber wenn du es nicht tust, wird es auf überraschende Weise durchbrechen (fooObj wird ein Null-Zeiger sein, sobald privateMethod1 zurückkehrt, selbst wenn es mehr Sachen gibt, die du damit machen möchtest). – sth

+0

stimmte mit etw überein, wenn natürlich. Warum sollte auto_ptr verwendet werden, wenn scoped_ptr eindeutig die bessere Wahl ist? Übertragung des Eigentums war nicht beabsichtigt. –

+0

Jungs, ich habe keinen Boost auf meinem Projekt. Deshalb habe ich eine solche STL-Lösung vorgeschlagen. Wo siehst du "Eigentumsübertragung"? –

1

I‘ Ich bin misstrauisch gegenüber dem Kommentar "es verwendet eine Bibliothek, die keine Objekte auf dem Stapel erlaubt, sie müssen auf dem Heap sein."

Warum? Das bedeutet normalerweise, dass sie auf eine spezielle Art und Weise aufgelöst werden müssen - also wird vielleicht keine dieser Lösungen funktionieren.

+0

@Earwicker der Compiler, den wir verwenden, ist Borland C++ und die Bibliothek, die wir verwenden, ist die VCL-GUI-Bibliothek, die mit C++ gebündelt ist. Das wird sich bald ändern, aber dafür muss ich jetzt bleiben. Aus irgendeinem Grund muss VCL auf dem Heap zugewiesen werden, ich habe keine wirkliche Idee warum. –

+0

Wahrscheinlich bedeutet dies, dass die Bibliothek über Factory-Methoden verfügt, die Zeiger auf erstellte Objekte zurückgeben und den Besitz an den Benutzer weitergeben. –

+0

Sind Sie sicher, dass Sie die Objekte löschen müssen? Ich habe noch nie VCL verwendet, aber ich habe die vage Vorstellung, dass Komponenten automatisch gelöscht werden, wenn ihre Eltern gelöscht werden. –

3

Eine weitere Möglichkeit ist, das Objekt als static_ptr für einfache Speicherverwaltung zu schaffen, sondern nur den rohen Zeiger auf die anderen privaten Methoden übergeben:

void privateMethod1(Foo *fooObj); 

void showSomethingOnTheScreen() { 
    scoped_ptr<Foo> fooObj(new Foo); 
    privateMethod1(fooObj.get()); 
}; 
3

I scoped_ptr innen showSomethingOnTheScreen verwenden würde, aber ein Pass roher Zeiger (oder Verweis) auf privateMethod1, z

scoped_ptr <Foo> fooObj (neuer Foo);
privateMethod1 (fooObj.get());

+0

Das war meine wirkliche Vermutung, aber ist diese Praxis empfohlen? Wenn es das ist, was ich tun werde –

0

In diesem Fall müssen Sie nur den Zuweisungsmechanismus ersetzen.
Erstellen Sie das Objekt auf dem Heap, übergeben Sie das Objekt jedoch als Verweis auf private Methoden.

class A { 
    private: 
     void privateMethod1(Foo& fooObj); 

    public: 
     void showSomethingOnTheScreen() { 
      scoped_ptr<Foo> fooObj(new Foo); 
      privateMethod1(*(fooObj.get())); 
     }; 
};