用于shared_ptr <>的自定义删除器,给出“无上下文错误”

时间:2019-07-18 20:47:14

标签: c++ c++11

#include <memory>
#include <iostream>
using namespace std;
class A
{
    public:
    int val;
    void deleter(A *x)
    {
        cout << "In Delete" << endl;
    }

    void push_back(int val)
    {
        shared_ptr<A> temp = (new int(val),deleter);
        cout << temp.use_count() << endl;
    }

};


int main()
{
    A a;
    a.push_back(11);
    return 0;
}

这会出现以下错误。

test.cpp: In member function 'void A::push_back(int)':
test.cpp:17:44: error: no context to resolve type of '((A*)this)->A::deleter'
         shared_ptr<A> temp = (new int(val),deleter);

通常,我正在尝试为shared_ptr实现一个自定义删除程序,这是嵌套类的成员函数,并且遇到了可怕的C ++错误。所有的google示例都是deleter是全局函数的示例。

我在这里想念什么?

建议1 : 根据第一个建议,我更改为以下内容。

class A;
    void deleter(A *a)
    {
        cout << "In destrcu" << endl;
    }
class A
{
    public:
    int val;

    void push_back(int val)
    {
        shared_ptr<A> temp = (new int(val),deleter);
        cout << temp.use_count() << endl;
    }

};

我仍然收到此错误,

test.cpp: In member function 'void A::push_back(int)':
test.cpp:16:43: error: conversion from 'void(A*)' to non-scalar type 'std::shared_ptr<A>' requested
         shared_ptr<A> temp = (new int(val),deleter);

2 个答案:

答案 0 :(得分:5)

首先,您会遇到一些错别字/语法错误

void push_back(int val)
{
    shared_ptr<A> temp = (new int(val),deleter);
    cout << temp.use_count() << endl;
}

shared_ptr<A> temp = (new int(val),deleter);

应该是

shared_ptr<A> temp = shared_ptr<A>(new int(val),deleter);
//or
shared_ptr<A> temp(new int(val),deleter);

然后

new int(val)

是不正确的,因为您正在创建int*并尝试初始化指针temp持有的指针,但是您不能这样做,因为temp持有A*,而不是int*。如果要设置val成员的值,则需要A的构造函数,并使用int。拥有

A(int val) : val(val) {}

让你写

shared_ptr<A> temp(new A(val),deleter);

但是deleter仍然存在问题。 deleter是一个非静态成员函数,这意味着没有类的实例就无法调用它。这意味着您要么需要制作deleter static,在这种情况下就可以了,因为您不需要A中的deleter对象。如果需要具有非静态成员函数,则可以使用lambda将deleter的对象绑定在一起。看起来像

shared_ptr<A> temp(new A(val),[this](auto ptr){ deleter(ptr) }); // capture the current object
//or
A delete_obj(some_value);
shared_ptr<A> temp(new A(val),[=](auto ptr){ delete_obj.deleter(ptr) }); // captures a object for itself

答案 1 :(得分:1)

删除器将由共享指针这样调用:

int GetToEndLine(char input[], char line[], int start) {
    int c,
        i = 0;
    for (; (c = input[start + i]) != '\n' && c != '\0'; ++i)
        line[i] = c;
    line[i] = c; // What is the purpose of this?
    return start + i;
}

您的删除器无法像这样被调用。必须改为这样调用:

deleter(pointer);

这是因为删除程序是指向非静态成员函数的指针。

解决方案:请勿使用非静态成员函数作为删除器。


(object.*deleter)(pointer);

剩下的问题是您的删除程序只能删除void deleter(A *a) shared_ptr<A> temp = (new int(val),deleter); 类型的指针。但是您正在尝试使用它来删除A*