C++ 静态字段的析构函数。单例实现
因此,经典的简单单例实现如下:C++ 静态字段的析构函数。单例实现,c++,design-patterns,static,singleton,C++,Design Patterns,Static,Singleton,因此,经典的简单单例实现如下: class Singleton { private: static Singleton* singleton; Singleton() {} public: static Singleton* getInstance(); }; cpp文件: Singleton* Singleton::singleton = 0; Singleton* Singleton::getInstance() { if (!single
class Singleton
{
private:
static Singleton* singleton;
Singleton() {}
public:
static Singleton* getInstance();
};
cpp文件:
Singleton* Singleton::singleton = 0;
Singleton* Singleton::getInstance()
{
if (!singleton)
{
singleton = new Singleton;
}
return singleton;
}
我在这里看到内存泄漏-'因为没有删除新的。但是C++中没有静态析构函数,所以我们不关心内存泄漏。 < P>内存泄漏不仅仅是没有匹配的分配。当你拥有可以回收的内存时,因为对象不再被使用,但实际上不会被释放。事实上,许多内存泄漏都是程序中有代码来释放内存,但不管出于什么原因,它都不会被调用(例如,引用周期)。有很多关于如何检测这类泄漏的研究就是此类工具的一个很好的例子 在单例的情况下,我们没有泄漏,因为单例存在于整个程序中。它的生命周期永远不会结束,因此没有回收内存不是问题 也就是说,您上面的代码并不是大多数人实现单例的方式。典型的C++实现将是这样的:
class Singleton
{
private:
/* No instantiation. */
Singleton() {}
/* Explicitly disallow copying. */
Singleton(const Singleton&) = delete;
Singleton& operator= (const Singleton&) = delete;
/* In C++03, the above would be written as
*
* Singleton(const Singleton&);
* Singleton& operator= (const Singleton&);
*
* and you'd just leave the methods unimplemented.
*/
public:
static Singleton& getInstance();
};
.cpp文件:
Singleton& Singleton::getInstance() {
/* Have a static local variable representing the unique instance. Since
* it's static, there is only one instance of this variable. It's also only
* initialized when getInstance is called.
*/
static Singleton theInstance;
return theInstance;
}
现在根本没有动态分配——内存是由编译器分配的,可能驻留在代码或数据段中,而不是堆中。还请注意,您必须明确禁止复制,否则您可能会得到许多单例克隆
另一个优点是C++保证在程序退出(假设程序正常终止)时,<>代码>析构函数>实例 >在程序结束时确实会被触发。因此,您可以使用所需的所有清理代码定义析构函数
希望这有帮助 当new
虽然没有实际的内存泄漏(在大多数现代操作系统中),但更糟糕的是,Singleton
析构函数没有被调用。如果你获得了一些资源,它们肯定会泄漏
这里可以做什么
使用智能指针存储实例,考虑<代码> STD::UNQuYGYPTR <代码>(用C++ 11)或<代码> Boo::AutoPyPTR
< P>当函数的变量局部被声明为“static”时,这意味着它没有被分配到堆栈上,并且它的值在一次调用到下一次调用时保持不变。单例在程序的整个生命周期中都是有用的。请参阅(或者只搜索单例,您会发现很多信息)这看起来像是在C#中重写的单例实现:但在C#中,“新建”不需要“删除”@SChepurin这个例子来自GoFbook@Hate.Nothing太好了。关于单身汉的删除有很多需要讨论的问题“单身汉是如何被删除的?”:what is=delete;您不是每次调用getInstance()时都要声明新的静态实例吗?@Hate-=delete
是一种新的C++11语法,用于显式标记函数不存在且无法调用。在C++03中,您只需声明这些函数,而不实现它们。此外,您没有每次都获得实例的新副本的原因是,局部变量被标记为static
,这意味着该变量只存在一个副本,并且在函数调用中保持不变。这回答了你的问题吗?或者还有什么我可以澄清的吗?我看到静态单态的存在;创建静态变量,我知道静态变量在程序运行时始终存在。但当你第二次调用这个函数时,它是否愿意创建新的静态变量theInstance,并且不会出现重新定义错误?@Hate-Nope。静态局部变量与静态全局变量相似,实际上只存在一个副本。如果多次调用该函数,它总是引用同一个静态局部变量。有关更多详细信息,请参阅;静态试验;静态试验;它给我一个重新定义测试的错误。@Lol4t0-我代码中的版本也被延迟初始化static
局部变量只有在第一次调用包含它们的函数时才会初始化。@templatetypedef,您在函数中定义了它,然后确定。@Lol4t0:您和templatetypedef给出了两条相互矛盾的语句:您说单例析构函数没有被调用,虽然他们说当程序完成时析构函数会被触发。既然这正是我来这里要了解的,你介意确认还是否认你的说法吗?@Larry:这取决于单例实现。问题主体中的实现不是激发析构函数,而是templatetypedef的实现。@Lol4t0谢谢!所以动态内存似乎没有被破坏,只是被释放了。