最近我碰到了C++的Singleton设计模式的实现/实现.看起来像这样(我从现实生活中采用了它):
// a lot of methods are omitted here
class Singleton
{
public:
static Singleton* getInstance( );
~Singleton( );
private:
Singleton( );
static Singleton* instance;
};
Run Code Online (Sandbox Code Playgroud)
从这个声明我可以推断出实例字段是在堆上启动的.这意味着存在内存分配.对我来说完全不清楚的是,什么时候内存将被解除分配?还是有漏洞和内存泄漏?好像在实施中存在问题.
我的主要问题是,如何以正确的方式实施它?
请考虑以下文本:
[C++11: 12.4/11]:隐式调用析构函数
- 对于在程序终止时具有静态存储持续时间(3.7.1)的构造对象(3.6.3),
- 对于在线程出口处具有线程存储持续时间(3.7.2)的构造对象,
- 对于具有自动存储持续时间(3.7.3)的构造对象,当创建对象的块退出时(6.7),
- 对于临时对象的生命周期结束时构造的临时对象(12.2),
- 对于由new-expression(5.3.4)分配的构造对象,通过使用delete-expression(5.3.5),
- 在几种情况下由于处理异常(15.3).
如果声明了类类型的对象或其数组,并且在声明的点处无法访问类的析构函数,则程序是不正确的.也可以显式调用析构函数.
那为什么这个程序编译成功呢?
#include <iostream>
struct A
{
A(){ };
~A() = delete;
};
A* a = new A;
int main() {}
// g++ -std=c++11 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
Run Code Online (Sandbox Code Playgroud)
GCC是否只是宽容?
我倾向于这样说,因为它拒绝了以下内容,但标准似乎没有特定于删除继承层次结构中的析构函数的特定规则(唯一松散相关的措辞与默认默认构造函数的生成相关):
#include <iostream>
struct A
{
A() {};
~A() = delete;
};
struct B : A {};
B *b = new B; // error: use of deleted function
int main() {}
Run Code Online (Sandbox Code Playgroud) 在这个问题中,陈述了这个结构防止实例的堆栈分配.
class FS_Only {
~FS_Only() = delete; // disallow stack allocation
};
Run Code Online (Sandbox Code Playgroud)
我的问题是,它如何阻止分配?我理解,无法显式或隐式删除此实例.但我认为,这将分别导致内存泄漏或运行时错误.
编译器是否足够聪明以排除这种情况并引发编译器错误?还有为什么需要这个呢?
我只是好奇这个代码是否会造成多个内存泄漏,或者它是否会被正确清理.
Node *newNode;
for (int i = 0; i < 10; i++)
{
newNode = new Node();
}
delete newNode;
Run Code Online (Sandbox Code Playgroud)
显然,代码没有做任何事情,但它确实帮助我解释了我的场景.我分配内存10次,当我删除指针留下9个孤儿?或者我是否重复使用相同的空间并正确删除孤儿?提前致谢!