2016-03-04 12 views
6

Próbowałem użyć std :: shared_pointer z deleterem. Próbowałem użyć funkcji członka jako deletera. Jednak nie mógł się skompilować. Kompilator dał mi komunikat o błędzie, ale nie mogłem zrozumieć, dlaczego to nie zadziałało. Czy ktoś wie, dlaczego to nie zadziałało? Dziękuję Ci bardzo.wskaźnik funkcji członka w konstruktorze

uproszczony kod jest następujący,

#include <memory> 

class MemberFunctionPointerInConstructor { 
public: 
    MemberFunctionPointerInConstructor(void) { 
     std::shared_ptr<int> a = std::shared_ptr<int>(new int(1), deleter); // this line makes a compiler error message 
    } 

    void deleter(int* value) { 
     delete value; 
    } 
}; 

Komunikat o błędzie z kompilatora jest następująca,

error: invalid use of non-static member function 
std::shared_ptr<int> a = std::shared_ptr<int>(new int(1), deleter); 
                   ^

Dziękuję bardzo.

Odpowiedz

3

Jeśli chcesz używać non-statycznej funkcji składowej jako Deleter , musisz powiązać go z instancją —, ale pamiętaj, że instancja musiałaby nadal być aktywna, gdy wywoływacz jest wywoływany. Na przykład:

class ShorterName { 
public: 
    ShorterName(void) { 
     using namespace std::placeholders; 
     auto a = std::shared_ptr<int>(new int(1), 
        std::bind(&A::deleter, this, _1)); 
    } 

    void deleter(int* value) { 
     delete value; 
    } 
}; 

Jeśli nie potrzebujesz konkretnej instancji, możesz ustawić ją jako statyczną, więc nie wymaga ona instancji.

class ShorterName { 
public: 
    ShorterName(void) { 
     auto a = std::shared_ptr<int>(new int(1), deleter); 
    } 

    static void deleter(int* value) { 
     delete value; 
    } 
}; 
+0

Dziękuję Yam Marcovic. – mora

8

Aby skorzystać z funkcji członka, który nie jest związany z instancją klasy trzeba by zadeklarować metodę static

static void deleter(int* value) { 
    delete value; 
} 
+0

Urocza prosta odpowiedź. :) – erip

+0

Dziękuję CoryKramer za skupioną odpowiedź. – mora

3

Istnieje kilka sposobów rozwiązania tego problemu. Jeśli faktycznie oznaczać zakaz statycznej funkcji członek, jeden sposób na to (nie jedynym) byłaby przez lambda function:

class MemberFunctionPointerInConstructor { 
public: 
    MemberFunctionPointerInConstructor() { 
     std::shared_ptr<int> a = std::shared_ptr<int>(
      new int(1), 
      [this](int *p){this->deleter(p);}); 
    } 

    void deleter(int* value) { 
     delete value; 
    } 
}; 
+0

Dziękuję Ami Tavory ponownie. To najlepsza odpowiedź dla mnie. Pozwól, że spytam cię o kolejną przysługę. Jeśli używam lamda, czy zajmuje dodatkową pamięć wskaźnika p w swoim obiekcie LAMDA? Jestem ciekawy rozmiaru pamięci. – mora

+0

@mora Nie do końca pewna, co masz na myśli. 'P' jest * placeholder * - mówi" kiedy wiesz, które 'p' chcesz usunąć, wywołaj tą funkcję za pomocą". Jednak lambda przechowa 'this' - musi to zapamiętać. –

+0

Dziękuję za odpowiedź. To, co chciałem wiedzieć, to sizeof (MemberFunctionPointerInConstructor). Nie mogłem wymyślić testu przez sizeof (...), kiedy cię zapytałem. To było 1. Nie zawiera dwóch wskaźników, * tego ani * p. W każdym razie jeszcze raz dziękuję. – mora

1

Odpowiedź jest bardzo prosta.

static void deleter(int* value) { 
    delete value; 
} 

Musisz sprawić, że funkcja statyczna, ponieważ w przeciwnym razie może używać zmiennych członkiem tej klasy, które można tylko zrobić, jeśli nie jest to przykład na to, aby być wykonane z, a tu, że nie jest to przypadek.

+0

Dziękuję marci sz. – mora

Powiązane problemy