2016-03-04 18 views
6

Tôi đã cố gắng sử dụng lệnh std :: shared_pointer với deleter. Tôi đã cố gắng sử dụng một hàm thành viên làm deleter. Tuy nhiên nó không thể biên dịch được. Trình biên dịch đã cho tôi một thông báo lỗi nhưng tôi không thể hiểu tại sao nó không hoạt động. Có ai biết tại sao nó không hoạt động? Cảm ơn nhiều.con trỏ hàm thành viên trong hàm tạo

đang Giản đang theo,

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

Các thông báo lỗi từ trình biên dịch được sau,

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.

Trả lời

3

Nếu bạn muốn sử dụng một hàm thành viên không tĩnh như một deleter , bạn phải liên kết nó với một cá thể — nhưng lưu ý rằng cá thể sẽ cần phải vẫn còn sống khi deleter được gọi. Ví dụ:

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

Nếu bạn không cần một trường hợp cụ thể, bạn có thể làm cho hàm tĩnh, do đó không yêu cầu cá thể.

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

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

Cảm ơn bạn Yam Marcovic. – mora

8

Để sử dụng một hàm thành viên không được liên kết với một thể hiện của lớp của bạn, bạn muốn đã tuyên bố phương pháp static

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

Câu trả lời đơn giản đáng yêu. :) – erip

+0

Cảm ơn bạn CoryKramer cho một câu trả lời tập trung. – mora

3

Có một số cách để giải quyết vấn đề này. Nếu bạn thực sự có nghĩa là một hàm thành viên không tĩnh, một cách để làm như vậy (không chỉ là một) sẽ được thông qua một 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

Cảm ơn bạn Ami Tavory một lần nữa. Đó là câu trả lời tốt nhất cho tôi. Hãy để tôi hỏi bạn một ưu tiên khác. Nếu tôi sử dụng lamda, có phải mất thêm bộ nhớ của con trỏ p trong đối tượng lamda của nó? Tôi tò mò về kích thước bộ nhớ. – mora

+0

@mora Không chắc chắn ý bạn là gì. 'P' là một * placeholder * - nó nói" khi bạn biết 'p' nào bạn muốn xóa, hãy gọi hàm này với nó". Các lambda sẽ lưu trữ 'này', mặc dù - nó cần phải nhớ nó. –

+0

Cảm ơn bạn đã trả lời. Những gì tôi muốn biết là sizeof (MemberFunctionPointerInConstructor). Tôi không thể nghĩ về kiểm tra bởi sizeof (...) khi tôi hỏi bạn. Nó là 1. Nó không bao gồm hai con trỏ, * điều này cũng không * p. Dù sao cảm ơn bạn một lần nữa. – mora

1

Câu trả lời là rất đơn giản.

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

Bạn phải thực hiện chức năng tĩnh, bởi vì nếu không nó có thể sử dụng các biến thành viên của lớp đó, có thể được chỉ được thực hiện nếu có một ví dụ cho nó được thực hiện với, và đây không phải là trường hợp.

+0

Cảm ơn marci sz. – mora

Các vấn đề liên quan