【问题标题】:to use self-defined deleter in shared_ptr在 shared_ptr 中使用自定义删除器
【发布时间】:2016-12-18 10:00:54
【问题描述】:

我定义了一个类,它有一个成员模板,代替 std::shared_ptr 的默认删除器:

class DebugDelete {
    public:
        DebugDelete(std::ostream &s = std::cerr): os(s) { }
        // as with any function template, the type of T is deduced by the compiler
        template <typename T> void operator()(T *p) const
        {
           os << "deleting unique_ptr" << std::endl;
           delete p;
        }
    private:
        std::ostream &os;
};

当我将它应用到以下代码时,报告了一些错误:

class A {
    public:
        // [Error] class 'A' does not have any field named 'r'
        A(std::shared_ptr<std::set<int>> p): r(p) { } // 1: How can I use self-defined deleter to initialize r in constructor
        A(int i): s(new std::set<int>, DebugDelete()) { } // 2: OK, what is the difference between this constructor and 3
    private:
        // [Error] expected identifier before 'new'
        // [Error] expected ',' or '...' before 'new'
        std::shared_ptr<std::set<int>> r(new std::set<int>, DebugDelete()); // 3: error
        std::shared_ptr<std::set<int>> s;
};

【问题讨论】:

  • 我怀疑您收到的许多错误与自定义删除无关。当然,在您的问题中包含实际的错误消息(应该始终这样做)将证实这一点。
  • @WhozCraig 我已经在代码中添加了错误消息。
  • 你不能用这种语法初始化一个类中的成员。尝试使用大括号或等号初始化程序。
  • @n.m.但是在成员函数中,我标记为 3 的行有效,就像我评论 Blue moe 的答案一样。
  • 在成员函数中是一回事。不在成员函数中是另一回事。无论如何,总是使用大括号:std::shared_ptr&lt;std::set&lt;int&gt;&gt; r{new std::set&lt;int&gt;, DebugDelete()};

标签: c++ templates shared-ptr


【解决方案1】:

在initialize_list中你可以使用自定义删除器

shared_ptr<set<int>> r = shared_ptr<set<int>>(new set<int>, DebugDelete());

而且你不应该使用一个 shared_ptr 来初始化另一个。

【讨论】:

  • 我按照你说的修改了我的代码并编译了。但我还定义了 A 类的成员函数 - void B() { shared_ptr&lt;set&lt;int&gt;&gt; ptr(new set&lt;int&gt;, DebugDelete()); } - publicprivate 都编译。它是怎么发生的?
  • 你的函数 void B() 是一个名为 ptr 的 shared_ptr 的构造函数。我的答案是分配一个成员变量。在 C++11 标准中,成员变量可以在类定义中初始化。示例:link
  • n.m. 的答案是另一种初始化成员变量的方法。Initializer_lists,见:link
  • 你的地图map&lt;string, shared_ptr&lt;set&lt;int&gt;&gt;&gt; m可以像shared_ptr&lt;set&lt;int&gt;&gt; ptr = shared_ptr&lt;set&lt;int&gt;&gt;(new set&lt;int&gt; , DebugDelete()); m["onestring"] = ptr; 一样使用,或者typedef map&lt;string,shared_ptr&lt;set&lt;int&gt;&gt;&gt;::value_type S_SP; m = {S_SP("string",ptr), another S_SP...};地图的元素是键值对,你只需要传递一个对>> ,它会编译
  • 非常感谢您。我已经将我的代码作为你的方法修复了。
猜你喜欢
  • 2020-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多