时,自定义删除器是否负责释放该内存?-6ren"> 时,自定义删除器是否负责释放该内存?-智能指针对我来说是一个新概念。我一直在尝试使用带有自定义删除器 (unique_ptr) 的智能指针围绕 fopen_s 和 fclose 包装一个 File 类。 下面是我的尝试。它成功地编译、运行-6ren">
gpt4 book ai didi

c++ - 当使用 "new"初始化 unique_ptr 时,自定义删除器是否负责释放该内存?

转载 作者:行者123 更新时间:2023-11-30 00:42:42 25 4
gpt4 key购买 nike

智能指针对我来说是一个新概念。我一直在尝试使用带有自定义删除器 (unique_ptr) 的智能指针围绕 fopen_s 和 fclose 包装一个 File 类。

下面是我的尝试。它成功地编译、运行并生成了一个名为“text.txt”的文件,其内容如预期的那样为“Hello World”。

我不得不在我的 Open 函数中使用“new”来初始化 unique_ptr,因为 make_unique 似乎无法与自定义删除器一起使用。由于我使用的是"new",我的自定义删除器是否负责释放分配的内存?

我已经逐步完成了我的程序(VS2019)。 File::Close 只被调用一次。我希望当我的 File:Open 函数中的“句柄”超出范围时调用它,但事实并非如此。此行为可能会受到对 std::move() 的调用的影响。不确定如何进一步调查这里发生的事情。

#include <Windows.h>
#include <memory>
#include <string>
#include <map>

class File
{

private:

//functors - custom deleter
struct Close { void operator()(FILE** _handle); };

//type definitions
typedef std::unique_ptr<FILE*,File::Close> Handle;
typedef std::map<std::string,Handle> HandleMap;

//static members
static Handle& Open(std::string _name, std::string _mode);
static HandleMap s_handle_map_;

//variables
Handle& handle_;
std::string name_;

public:

//functions
File(std::string _name, std::string _mode);
void Write(std::string _message);

};

File::HandleMap File::s_handle_map_;

File::File(std::string _name, std::string _mode)
:handle_(Open(_name,_mode)),
name_(_name)
{
}

File::Handle& File::Open(std::string _name, std::string _mode)
{
bool exist = s_handle_map_.count(_name) > 0;

if (!exist)
{
Handle handle(new FILE*(nullptr));

//open new file
fopen_s(
handle.get(),
_name.c_str(),
_mode.c_str()
);

//transfer ownership of handle
s_handle_map_.emplace(
_name,
std::move(handle)
);

}

return s_handle_map_[_name];
}

void File::Close::operator()(FILE** _handle)
{
fclose(*_handle);
*_handle = nullptr;

//necessary?
delete _handle;
_handle = nullptr;
}

void File::Write(std::string _message)
{
fprintf(*handle_, _message.c_str());
}

int WINAPI WinMain(HINSTANCE _instance, HINSTANCE _previous, LPSTR _cmd, int _show)
{
File file("test.txt","w");
file.Write("Hello World\n");
return 0;
}

最佳答案

每当你想到unique_ptr<FILE*, ...> ,深吸一口气,等一下,然后继续 fstream .

以下代码做同样的事情,但依赖于经过验证和测试的 C++ 标准库。 fstream 具有您期望的所有功能,包括在不再需要时自动关闭:

int WINAPI WinMain(HINSTANCE _instance, HINSTANCE _previous, LPSTR _cmd, int _show)
{
fstream file("test.txt", fstream::out);
file << "Hello World\n";
return 0;
}

而且您根本不需要担心内存管理。

现在,概括您的问题:

  • 如果你创建一个 unique_ptr<T,D> 你自己基于 new T指针,自定义删除器 D将有责任delete T .如果不这样做,您将泄漏内存 ( example )。
  • 因此,更好的方法是继续使用默认删除器,并确保 T 的析构函数将清除或关闭任何需要的东西。
  • 一旦你选择默认删除器,最好的选择是make_unique。与新方法 (see here why) 相比有一些优势

关于c++ - 当使用 "new"初始化 unique_ptr<FILE*,File::Close> 时,自定义删除器是否负责释放该内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58565711/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com