受保护析构函数的基本原理
Rationale for protected destructor
我注意到很多 Poco 类 都有一个受保护的析构函数。这让他们编码起来更烦人。例如,这是我的一些代码:
struct W2: Poco::Util::WinRegistryConfiguration
{
typedef Poco::Util::WinRegistryConfiguration inherited;
using inherited::inherited;
};
std::string get_documents_folder()
{
W2 regc { "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" };
return regc.getString("Personal", "");
}
当然,如果我可以取消 W2
并只使 regc
具有类型 WinRegistryConfiguration
,那就简单多了。但由于受保护的析构函数,这是不可能的。
我意识到可以改用 Poco::AutoPtr
,但是当自动分配应该正常工作时,使用 new
进行动态分配会浪费资源。
我的问题是:这样做的理由是什么?我是否忽略了什么?
原因是 WinRegistryConfiguration 是引用计数的(继承自 Poco::RefCountedObject)。受保护的析构函数旨在防止客户端实例化堆栈上的 class 或直接删除对象。相反,您应该通过 new
实例化 class,并通过 RefCountedObject 方法管理生命周期。
我对 Poco 不熟悉,但应该还有一个智能指针 class 通过自动调用 RefCountedObject 方法来管理引用计数对象。
正如已经回答的那样,Poco::RefCountedObject 具有受保护的析构函数,因此无法在堆栈上创建从它继承的所有 类。原因是因为当引用计数达到零时它们会自行删除,因此在堆栈上创建它们会导致未定义的行为 - 它们主要用于 Poco::AutoPtr,但这不是强制性的 - 您也可以手动引用计数,使用 duplicate() 和 release().
查看您的代码,您可能正在寻找 WinRegistryKey,您可以像这样使用它:
std::string get_documents_folder()
{
Poco::Util::WinRegistryKey regKey("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders");
return regKey.getString("Personal", "");
}
我注意到很多 Poco 类 都有一个受保护的析构函数。这让他们编码起来更烦人。例如,这是我的一些代码:
struct W2: Poco::Util::WinRegistryConfiguration
{
typedef Poco::Util::WinRegistryConfiguration inherited;
using inherited::inherited;
};
std::string get_documents_folder()
{
W2 regc { "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" };
return regc.getString("Personal", "");
}
当然,如果我可以取消 W2
并只使 regc
具有类型 WinRegistryConfiguration
,那就简单多了。但由于受保护的析构函数,这是不可能的。
我意识到可以改用 Poco::AutoPtr
,但是当自动分配应该正常工作时,使用 new
进行动态分配会浪费资源。
我的问题是:这样做的理由是什么?我是否忽略了什么?
原因是 WinRegistryConfiguration 是引用计数的(继承自 Poco::RefCountedObject)。受保护的析构函数旨在防止客户端实例化堆栈上的 class 或直接删除对象。相反,您应该通过 new
实例化 class,并通过 RefCountedObject 方法管理生命周期。
我对 Poco 不熟悉,但应该还有一个智能指针 class 通过自动调用 RefCountedObject 方法来管理引用计数对象。
正如已经回答的那样,Poco::RefCountedObject 具有受保护的析构函数,因此无法在堆栈上创建从它继承的所有 类。原因是因为当引用计数达到零时它们会自行删除,因此在堆栈上创建它们会导致未定义的行为 - 它们主要用于 Poco::AutoPtr,但这不是强制性的 - 您也可以手动引用计数,使用 duplicate() 和 release().
查看您的代码,您可能正在寻找 WinRegistryKey,您可以像这样使用它:
std::string get_documents_folder()
{
Poco::Util::WinRegistryKey regKey("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders");
return regKey.getString("Personal", "");
}