c++ - 基类如何禁用派生类的构造函数

标签 c++ templates inheritance singleton

我尝试编写一个单例类,这样一个类只需要从它派生并自动成为单例:

基类:

 template <class T>
 class Singleton
 {
 private:
     static T* instance;
 public:

     static T* getInstance(void)
     {
         if(!instance)
             instance = new T;
         return instance;
     }

     static void release(void)
     {
         if(instance)
         {
             delete instance;
             instance = NULL;
         }
     }
 };

 template <class T>
 T* Singleton<T>::instance = NULL;

我的派生类:

#include <iostream>
#include "Singleton.h"

class MySingleton : public Singleton<MySingleton>
{
public:
    void helloWorld(void)
    {
        printf("Hello, World!\n");
    }
};

主要内容:

int main(int argc, const char * argv[])
{
    MySingleton* s = MySingleton::getInstance();
    s->helloWorld();
    return 0;
}

这很完美,但它不是真正的单例,因为我仍然可以使用它的默认构造函数构造 MySingleton。当然,我可以将 MySingleton 的 ctors 设为私有(private)并将 Singleton 声明为友元,但是有什么方法可以在基类中做到这一点,以便仅派生而不声明任何 ctors 就足以创建类单例?

最佳答案

由于您的基类模板必须构造单例对象,因此它需要访问具体类的构造函数。因此,该构造函数应该是公共(public)的,或者基类必须是具体类的友元。具体类中的公共(public) Ctor 是任何人都可以访问的,所以你不能在编译时禁止它的使用。 但是,您可以确保它只在运行时调用一次:

template <class T>
class Singleton
{
  /* ... */
  static bool instantiating;
protected:
  Singleton()
  {
    if (!instantiating) //not called in instance() function
      throw std::runtime_error("Don't call me!");
  }

public:
  static T* getInstance()
  {
    intantiating = true;
    instace = new T();
    instantiating = false;
  }
};

template <class T>
bool Singleton<T>::instantiating = false;

注意事项: - 我在这里使用的 instantiating 变量不是线程安全的 - instantiating 的 true/false 设置不是异常安全的(newT::T() 可能会抛出异常) - 将指针用作实例变量是不安全的并且容易出现内存泄漏。考虑使用 shared_ptr 或引用(Meyers 单例)

关于c++ - 基类如何禁用派生类的构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14256429/

相关文章:

windows-phone-7 - 为什么我从 LongListSelector 下降时收到 "well-formedness constraint: unique attribute spec"(0xc00cee3c) 错误

c++ - 选择性继承 C++

c++ - SQL Server - 未找到数据源名称且未指定默认驱动程序

c++ - 将 -M 标志添加到 g++ 会导致文件格式无法识别错误

c++ - 在 C++ 类中创建二维 vector

c++ - 仅为具有 operator/defined 的此类 T 创建模板 <T>

c++ - 实现接受索引数组的下标运算符

c++ - 在 C++ 编译时计算和打印阶乘

c++ - 是否可以将 libxml 与 unicode xmlchar 一起使用?

inheritance - 应用程序架构中具体继承的主要竞争设计模式是什么?