2009-03-17 14 views
5

Mam klasy, która tworzy obiekt wewnątrz jednej publicznej metody. Obiekt jest prywatny i niewidoczny dla użytkowników klasy. Metoda ta wywołuje inne prywatne metod wewnątrz tej samej klasy i przekazać utworzony obiekt jako parametr:Przekazywanie inteligentnego wskaźnika jako argumentu w klasie: scoped_ptr lub 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); 
     }; 
}; 

wierzę prawidłowe inteligentny wskaźnik w tym przypadku byłoby scoped_ptr jednak nie mogę zrobić to dlatego scoped_ptr sprawia, że ​​klasa non copyable jeśli używany w ten sposób, więc mam uczynić metody tak:

void privateMethod1(FooPtr& fooObj); 

privateMethod1 nie przechowuje obiekt, nie przechowuje referencje niego. Po prostu pobiera dane z klasy Foo.

Prawidłowy sposób prawdopodobnie nie używałby w ogóle inteligentnego wskaźnika i przydzielania obiektu do stosu, ale nie jest to możliwe, ponieważ używa biblioteki, która nie pozwala na obiekty na stosie, muszą one znajdować się na stertach .

W końcu nadal jestem zdezorientowany rzeczywistym użyciem scoped_ptr.

+1

Jestem ciekawa biblioteki, która "nie pozwala na obiekty na stosie". Czy obiekty są przydzielane wewnątrz biblioteki na stercie za pomocą fabryki? Czy biblioteka przejmuje na własność wskaźnik i usuwa go?Jakie są powody, dla których nie można używać obiektów przydzielonych do stosów? –

Odpowiedz

1

Używaj tutaj prostej std :: auto_ptr, ponieważ nie możesz tworzyć obiektów na stosie. I lepiej dla twojej prywatnej funkcji po prostu zaakceptuj surowy wskaźnik.

Prawdziwym zastosowaniem jest to, że nie musisz wychwytywać wszystkich możliwych wyjątków i wykonywać ręczne usuwanie.

W rzeczywistości, jeśli obiekt znajduje się nie zmienia przedmiotu oraz swój obiekt powrotną API na pewno lepiej używać

void privateMethod1(const Foo& fooObj); 

i przekazać obiekt istnieje jako

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

Ten koniec jest dokładnie taki sam jak w scoped_ptr, tylko że nie wymusza na nim deklaracji parametrów metody jako referencji. Ale jeśli tego nie zrobisz, zadziwi to w zaskakujący sposób (fooObj będzie wskaźnikiem Null, gdy privateMethod1 powróci, nawet jeśli jest więcej rzeczy, które chciałbyś z nim zrobić). – sth

+0

uzgodnione z czymś, jeśli oczywiście. dlaczego warto używać auto_ptr, jeśli scoped_ptr jest zdecydowanie lepszym wyborem? przeniesienie własności nie było zamierzone. –

+0

Chłopaki, nie mam doładowania w moim projekcie. Dlatego właśnie zaproponowałem takie rozwiązanie. Gdzie widzisz "przeniesienie własności"? –

1

I Jestem podejrzliwy w stosunku do komentarza "używa biblioteki, która nie pozwala na obiekty na stosie, muszą być na sterty."

Dlaczego? Zazwyczaj oznacza to, że muszą zostać zwolnione w jakiś specjalny sposób - więc być może żadne z tych rozwiązań nie zadziała.

+0

@Earwicker, którego używamy, to Borland C++, a biblioteka, której używamy, to biblioteka GUI VCL, która jest dołączona do C++. To się wkrótce zmieni, ale na razie muszę się z tym uporać. Z jakiegoś powodu VCL musi zostać przydzielony na kupce, nie mam pojęcia, dlaczego. –

+0

Prawdopodobnie oznacza to, że biblioteka ma fabryczne metody, które zwracają wskaźniki do utworzonych obiektów i przekazują prawo własności do użytkownika. –

+0

Czy na pewno chcesz usunąć obiekty? Nigdy nie użyłem VCL, ale mam niejasne pojęcie, że automatycznie usuwa komponenty po usunięciu ich rodziców. –

3

Kolejną możliwością jest utworzenie obiektu jako static_ptr dla ułatwienia zarządzania pamięcią, ale po prostu zdać surowy wskaźnik do innych metod prywatnych:

void privateMethod1(Foo *fooObj); 

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

użyłbym scoped_ptr wewnątrz showSomethingOnTheScreen, ale zdać surowy wskaźnik (lub odniesienie) do privateMethod1, np

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

+0

To było moje prawdziwe przypuszczenie, ale czy ta praktyka jest zalecana? Jeśli to jest to, co zrobię –

0

W takim przypadku wystarczy zastąpić mechanizm alokacji.
Utwórz obiekt na stercie, ale przekazuj obiekt jako odniesienie do metod prywatnych.

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

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