2016-03-04 82 views
6

我試圖將std :: shared_pointer與deleter一起使用。我試圖使用成員函數作爲刪除者。但它無法編譯。編譯器給了我一個錯誤消息,但我不明白爲什麼它不起作用。有人知道爲什麼它不起作用嗎?非常感謝你。構造函數中的成員函數指針

簡化代碼如下,

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

從編譯器中的錯誤消息之後,

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

非常感謝你。

回答

3

如果你想使用一個非靜態成員函數的刪除器,您必須將其綁定到實例—,但請注意,在調用刪除程序時,該實例仍需要保持活動狀態。例如,

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

如果您不需要特定情況下,可以使功能靜態的,所以它不需要一個實例。

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

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

謝謝Yam Marcovic。 – mora

8

要使用未綁定到你的類的實例成員函數你必須申報方法static

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

可愛簡單的答案。 :) – erip

+0

謝謝CoryKramer提供專注的答案。 – mora

3

有幾種方法可以解決這個問題。如果你真的意味着一個非靜態成員函數,這樣做(不是唯一的一個)的一個方法是通過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

謝謝阿米Tavory了。這對我來說是最好的答案。讓我再問你一個忙。如果我使用lamda,它是否需要在lamda對象中額外存儲指針p的內存?我很好奇內存大小。 – mora

+0

@mora不完全確定你的意思。 'p'是一個*佔位符* - 它說:「當你知道你想刪除哪個'p'時,用它調用這個函數。 lambda將存儲'this',但它需要記住它。 –

+0

謝謝你的回覆。我想知道的是sizeof(MemberFunctionPointerInConstructor)。當我問你時,我無法想象sizeof(...)的測試。它是1.它不包括兩個指針,* this和* p。無論如何,再次感謝你。 – mora

1

答案很簡單。

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

你必須做的函數靜態的,否則它可能會使用類,可如果有一個實例它與完成,並且在這裏,是不是這樣只能做到的成員變量。

+0

謝謝marci sz。 – mora