【问题标题】:std::unique_ptr custom deleterstd::unique_ptr 自定义删除器
【发布时间】:2013-03-30 19:49:41
【问题描述】:

参考Well, how does the custom deleter of std::unique_ptr work?

构造函数

std::unique_ptr<ErrorHandling> error_;

RecursiveDescentParser::RecursiveDescentParser(std::string inputStream, bool fileService, 
            boost::optional<std::string> filePathName, std::ofstream &writer){

    if (fileService == true){
        error_(new ErrorHandling(fileService, writer));  <---- compiler error
    }
    else{
        error_(new ErrorHandling(fileService, std::ofstream())); <---- compiler error
    }       
}

编译器错误

Error   1   error C2247: 'std::default_delete<_Ty>::operator ()' not accessible because 'std::unique_ptr<_Ty>' uses 'private' to inherit from 'std::_Unique_ptr_base<_Ty,_Dx,_Empty_deleter>'

错误原因描述here

我决定因为'std::default_delete&lt;_Ty&gt;::operator ()private,因为子类(在这种情况下为std::unique_ptr)指定了private inheritance,我将编写自己的自定义删除器。问题是我对成功的语法和符号太不舒服了。

【问题讨论】:

  • ErrorHandling 的析构函数是否声明了private
  • 我实际上没有声明一个析构函数(合成的)并正式声明了一个,但编译器错误仍然存​​在。

标签: c++ unique-ptr


【解决方案1】:

这一行

error_(new ErrorHandling(fileService, writer));

是一个错误,因为unique_ptr 没有operator()。错误消息有点误导,因为它的基类似乎有一个(但幸运的是私有的)。

你可能打算

error_.reset(new ErrorHandling(fileService, writer));

这使得unique_ptr 拥有一个新对象。

【讨论】:

  • 即使没有初始对象,调用reset来初始化一个std::unique_ptr是安全的吗?
  • 是的,您使用的默认构造函数会将初始指针设置为空。用真正的指针替换它是完全可以的。
【解决方案2】:

问题是您试图在unique_ptr 上使用函数调用运算符,这不是一个有效的做法。然后会引起一些混乱,因为您的特定实现恰好有一个不可访问的运算符,而不是根本没有运算符,从而给出了一个奇怪的错误消息。

我假设您实际上是在尝试重置 error_ 以拥有一个新指针:

error_.reset(new ErrorHandling(fileService, writer));
//    ^^^^^^

更新:如果您确实想要一个自定义删除器(重申一下,在这种情况下您不需要),它可能看起来像:

struct ErrorHandlingDeleter
{
    void operator()(ErrorHandling * p) {/* do something to release the pointer */}
};

std::unique_ptr<ErrorHandling, ErrorHandlingDeleter> error;

【讨论】:

  • 我正在尝试以下语法 std::unique_ptr&lt;ErrorHandling&gt; error_(new ErrorHandling(fileService, writer)); 但收到编译错误,我认为需要定义我自己的自定义删除器。即使使用reset 是解决方案,我可以看看SSCCE 自定义删除器示例吗?
  • @Mushy:这是声明和初始化一个新的唯一指针的语法。但是,您不想这样做;您想修改现有的,为此您需要致电reseterror_(some_pointer) 做了一些完全不同的事情——它试图像函数一样调用唯一指针,这是不可能的。
  • @Mushy:对于自定义删除器的示例,Google 向我指出了 stackoverflow.com/questions/8274451 和许多其他地方。但是,当然,您不想在这里使用自定义删除器;它们仅适用于 delete 不是正确的做法。
  • 我在问题顶部引用的那个链接。该链接的语法对我来说不是很清楚,因此我决定要求一个更清晰的示例。甚至我的教科书也没有提供一个非常清晰的例子。
  • @Mushy:好的,我添加了一个自定义删除器的示例。不过,我不知道这是否比你的教科书更清楚。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-04-09
  • 2018-01-02
  • 2017-05-15
  • 1970-01-01
  • 2018-01-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多