C++,再次调用单例类的析构函数

Sun*_*Lim 1 c++ singleton

我做了一个简单的单身课程.在运行测试时,我得到了一些结果.

再次调用析构函数.

这是结果和我的代码.

结果:我希望析构函数被调用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)

Yan*_*ang 7

实际上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)

这确保了任何人,甚至是类本身,都无法调用复制或复制赋值函数.

  • 如果C++ 11可用,最好更换那些`; //不要用`= ​​delete;`来实现`.这确保了任何人,甚至是类本身,都无法调用复制或复制赋值函数.并且您可以使用`= default;`而不是私有构造函数和析构函数的空括号. (4认同)