我做了一个简单的单身课程.在运行测试时,我得到了一些结果.
再次调用析构函数.
这是结果和我的代码.
结果:我希望析构函数被调用4次,因为我调用了GetInstance()4次.但 Desctuructor被召唤5次!
Start Test
TestClass Constructor
TestClass Destructor
TestClass Destructor
TestClass Destructor
TestClass Destructor
TestClass Destructor
Run Code Online (Sandbox Code Playgroud)
singleton.h
#ifndef SINGLETON_H_
#define SINGLETON_H_
#include "basictype.h"
namespace common {
namespace internal {
// Usage :
// MyClass mine = common::internal::Singleton<MyClass>::GetInstace();
// mine.foo();
// This Singleton class is maybe the best one avoiding memory allocation.
// See http://stackoverflow.com/questions/1008019/c-singleton-design-pattern/1008289#1008289
template <typename Type>
class Singleton {
public:
static Type& GetInstance() {
static Type instance;
return instance;
}
private:
Singleton() {};
DISALLOW_COPY_AND_ASSIGN(Singleton);
};
} // namespace internal
} // namespace common
#endif // SINGLETON_H_
Run Code Online (Sandbox Code Playgroud)
main.c中
#include <iostream>
#include "singleton.h"
class TestClass {
public:
TestClass() {
std::cout << "TestClass Constructor" << std::endl;
}
~TestClass() {
std::cout << " TestClass Destructor" << std::endl;
}
};
void runSingletonTest() {
TestClass tc = common::internal::Singleton<TestClass>::GetInstance();
TestClass tc2 = common::internal::Singleton<TestClass>::GetInstance();
TestClass tc3 = common::internal::Singleton<TestClass>::GetInstance();
TestClass tc4 = common::internal::Singleton<TestClass>::GetInstance();
}
int main(){
std::cout << "Start Test" << std::endl;
runSingletonTest();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
实际上TestClass,您的代码中有5个实例.
第一个是由创建的
static Type instance;
Run Code Online (Sandbox Code Playgroud)
使用默认构造函数.这会TestClass Constructor在输出中生成一行.
其他4个是由
TestClass tc = common::internal::Singleton<TestClass>::GetInstance();
TestClass tc2 = common::internal::Singleton<TestClass>::GetInstance();
TestClass tc3 = common::internal::Singleton<TestClass>::GetInstance();
TestClass tc4 = common::internal::Singleton<TestClass>::GetInstance();
Run Code Online (Sandbox Code Playgroud)
使用复制构造函数.复制构造函数由编译器生成,不输出任何内容(这就是为什么TestClass Constructor在输出中只看到一个).因此,有5个实例TestClass被破坏.
注意:你的Singleton班级不是真正的单身人士.要正确遵循单例模式,您应该通过将(复制)构造函数和析构函数声明为以下内容来禁止复制和赋值private:
template <typename Type>
class Singleton {
public:
static Type& GetInstance() {
static Type instance;
return instance;
}
private:
Singleton() {}
~Singleton() {}
// Dont forget to declare these two. You want to make sure they
// are unaccessable otherwise you may accidently get copies of
// your singleton appearing.
Singleton(const Singleton&); // Don't Implement
Singleton& operator=(const Singleton&); // Don't implement
};
Run Code Online (Sandbox Code Playgroud)
关于C++ Singleton设计模式有一些有用的讨论.
如果C++ 11可用,最好使用
private:
Singleton() = default;
~Singleton() = default;
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
Run Code Online (Sandbox Code Playgroud)
这确保了任何人,甚至是类本身,都无法调用复制或复制赋值函数.