Autor Wątek: C++, SDL i shared_ptr - jak używać?  (Przeczytany 4941 razy)

Offline Xirdus

  • Redaktor

# Marzec 16, 2014, 21:33:47
Kiedy jest sens używania inteligentnego wskaźnika lub wrappera a kiedy lepiej jest pozostać przy zwykłym?
Inteligentne wskaźniki i wrappery: kiedy piszesz w C++.
Zwykłe wskaźniki: kiedy piszesz w C.

Skoro narzut jest zerowy, to mój pomysł podmiany wszystkich wskaźników na shared_ptr ma sens?
Tu nie chodzi tylko o zapominalstwo z delete'ami - tu chodzi także o wygodę użycia. Np. jak zwracasz z funkcji wskaźnik na coś - wypadałoby to kiedyś usunąć, a z RAII wszystko usuwa się automatycznie.

To jest ogólnie rzecz biorąc nieprawda. Pośredni wskaźnik na obiekt to dodatkowy cache miss.
Z tym że struktura shared_ptra, oprócz wskaźnika na część share'owaną, zawiera też często wskaźnik bezpośrednio na obiekt - przynajmniej w tzw. "wszystkich popularnych implementacjach". Narzut pojawia się z użyciem weak_ptrów - przy czym ostrzegam, że gdy używa się samych shared_ptrów, też może się zdarzyć wyciek, dlatego gdzie się da należy go zastąpić weak_ptrem.

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline ison

  • Użytkownik

# Marzec 16, 2014, 21:46:25
Cytuj
To jest ogólnie rzecz biorąc nieprawda. Pośredni wskaźnik na obiekt to dodatkowy cache miss.
Ale tutaj porównujemy raw ptr -> smart ptr, a nie obiekt statyczny -> smart ptr.
Odwołanie do obiektu poprzez zwykły wskaźnik to też cache miss, tak samo jak w przypadku smart pointera, który przy wyłuskiwaniu obiektu robi dokładnie to samo co zwykły wskaźnik (get jak i -> są inline).
Zerowy narzut tyczył się wyłuskiwania, a nie smart pointerów ogólnie.
Jeśli jest jakiś jeszcze kruczek, to proszę mnie poprawić.

btw
#include <cstdio>

template <class T> class Pointer
{
    public:
        T *get() {return m_ptr;}
        void set(T *ptr) {m_ptr = ptr;}

    private:
        T *m_ptr;
};

int main()
{
    int a;
    scanf("%d", &a);

    Pointer <int> ptr;
    ptr.set(new int(a));

    printf("%d\n", *ptr.get());
}
kompiluje się do dokładnie tego samego co
#include <cstdio>

int main()
{
    int a;
    scanf("%d", &a);
    int *ptr = new int(a);
    printf("%d\n", *ptr);
}



@kwonitf
Cytuj
Teraz rozumiem to tak, że zostały one stworzone tylko po to żeby zabezpieczyć przed tym, że ktoś zapomni napisać delete'a. Czy ja wiem, czy to tak łatwo zapomnieć?
Prosty przykład:
float getSqrt(float val)
{
    SqrtCalculator *sqrtCalculator = new SqrtCalculator();
   
    if(val < 0.f) return std::numeric_limits <float>::quiet_NaN()

    float retValue = sqrtCalculator->getSquareRoot(val);
    delete sqrtCalculator;
    return retValue;
}
oczywiście bardzo abstrakcyjny, ale jest.

Cytuj
to mój pomysł podmiany wszystkich wskaźników na shared_ptr ma sens?
shared_ptr tylko wtedy, gdy wiesz, że będziesz w pewnym momencie musiał dzielić ownership obiektu. W innym wypadku unique_ptr - nie zawsze potrzebny jest reference counting.
Ogólnie przy inteligentnych wskaźnikach narzut wydajnościowy jest, ale niewielki i mało istotny w aplikacjach indie.
« Ostatnia zmiana: Marzec 16, 2014, 22:15:59 wysłana przez ison »

Offline Dab

  • Redaktor
    • blog

# Marzec 17, 2014, 12:36:36
Ale tutaj porównujemy raw ptr -> smart ptr, a nie obiekt statyczny -> smart ptr.

Tak. Zwracam honor, nie wczytałem się uważnie w całą dyskusję. :)

Offline ArekBal

  • Użytkownik

# Marzec 18, 2014, 01:29:27
Nie dramatyzujmy