2016-03-04 8 views
6

Ich habe versucht, std :: shared_pointer mit Deleter zu verwenden. Ich habe versucht, eine Member-Funktion als Deleter zu verwenden. Es konnte jedoch nicht kompiliert werden. Compiler gab mir eine Fehlermeldung, aber ich konnte nicht verstehen, warum es nicht funktioniert hat. Weiß jemand, warum es nicht funktioniert hat? Vielen Dank.Mitglied Funktionszeiger in Konstruktor

Simplified Code folgt,

#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; 
    } 
}; 

Die Fehlermeldung von Compiler wird wie folgt,

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

Thank you very much.

Antwort

3

Wenn Sie eine nicht-statische Member-Funktion als deleter verwenden möchten , Sie müssen es an eine Instanz binden —, aber beachten Sie, dass die Instanz immer noch am Leben sein muss, wenn der Deleter aufgerufen wird. Zum Beispiel

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; 
    } 
}; 

Wenn Sie nicht über eine bestimmte Instanz benötigen, können Sie die Funktion statisch machen, so dass es nicht eine Instanz erforderlich.

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

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

Danke Yam Marcovic. – mora

8

Um eine Member-Funktion zu verwenden, die nicht auf eine Instanz der Klasse gebunden ist, Sie static die Methode zu erklären müss

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

Schöne einfache Antwort. :) – erip

+0

Danke CoryKramer für eine konzentrierte Antwort. – mora

3

Es gibt mehrere Möglichkeiten, dies zu lösen. Wenn Sie tatsächlich eine nicht-statische Member-Funktion bedeuten, eine Möglichkeit, dies zu tun (nicht die einzigen) wäre durch ein 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

Danke Ami Tavory wieder. Es ist die beste Antwort für mich. Lass mich dich noch um einen Gefallen bitten. Wenn ich lamda verwende, braucht es extra Speicher von Zeiger p in seinem lamda-Objekt? Ich bin neugierig auf Speichergröße. – mora

+0

@mora Nicht genau, was du meinst. Das 'p' ist ein * Platzhalter * - es sagt" Wenn Sie wissen, welches 'p' Sie löschen möchten, rufen Sie diese Funktion mit". Das Lambda wird "dieses" jedoch speichern - es muss sich daran erinnern. –

+0

Vielen Dank für Ihre Antwort. Was ich wissen wollte, war sizeof (MemberFunctionPointerInConstructor). Ich konnte mir nicht vorstellen, nach Größe zu testen (...), als ich dich fragte. Es war 1. Es enthält keine zwei Zeiger, * dies noch * p. Wie auch immer, danke nochmal. – mora

1

Die Antwort ist sehr einfach.

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

Sie müssen die Funktion statisch machen, denn sonst könnte es Membervariablen dieser Klasse verwenden, die nur getan werden kann, wenn es eine Instanz für sie mit zu tun, und hier, dass nicht der Fall ist.

+0

Danke marci sz. – mora

Verwandte Themen