Skr*_*rug 1 c++ unique-ptr c++11
智能指针对我来说是一个新概念。我一直在尝试使用带有自定义删除器(unique_ptr)的智能指针将File类包装在fopen_s和fclose周围。
以下是我的尝试。它可以成功编译,运行并生成一个名为“ text.txt”的文件,其中包含预期的内容“ Hello World”。
由于make_unique不适用于自定义删除程序,因此我必须在“ Open”函数中使用“ new”来初始化unique_ptr。由于我使用的是“ new”,我的自定义删除程序负责释放分配的内存吗?
我已逐步完成程序(VS2019)。File :: Close仅被调用一次。我希望当File:Open函数中的“ handle”超出范围时会被调用,但事实并非如此。此行为可能会受到对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;
}
Run Code Online (Sandbox Code Playgroud)
每当您想到时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;
}
Run Code Online (Sandbox Code Playgroud)
您完全不必担心内存管理。
现在,概括您的问题:
unique_ptr<T,D>基于new T指针创建自己,则自定义删除器D将负责delete T。否则,您将泄漏内存(示例)。 make_unique就是比新方法具有一些优势(请参见此处的原因)| 归档时间: |
|
| 查看次数: |
79 次 |
| 最近记录: |