构造函数,析构函数不为public时

当constructor, destructor为protected时, 不允许实例化这个类,不管是在栈中还是在堆中, (但可以实例化派生类(protected 的 constructor可以在派生类中调用)) , 当在栈中实例化一个类时, 需要constructor和destructor都是public的, 而在堆中new时 ,需要constructor是public的,  而当调了delete时, 才需要destructor是public的  , 当constructor为private时,  不仅不允许实例化这个类, 也实例化不了派生类(private constructor只能在本类成员中调用),  而这种情况常用来实现 单例 设计模式

单例设计模式(Singleton) ,  在我们的talk中用到了 boost::pool::detail::Singleton_default 这个模板类来实现单例 , 但这是用于boost内部的, 在最新的版本中我就没有看到这个类了(这个有点像我研究enable_shared_from_this时的情况), 所以我们可以最好直接写单例类, 像直接把 boost的实现用过来也行,  boost/pool/detail/singleton.hpp 这个文件没有包含任何其它头文件,  以下是boost::pool某个版本的实现

 1 template<class T>
 2 class Singleton {
 3 private :
 4       struct  object_creator {
 5            object_creator() { Singleton<T>::instance(); }
 6            inline void do_nothing()  const{ }
 7       }
 8       static object_creator  create_object;
 9       Singleton();
10 public :
11       typedef   T  ObjectType;
12       static  ObjectType&  instance () {
13             static ObjectType obj;
14             create_object.do_nothing();
15             return obj;
16       }
17 }
18 template<class T>
19 typename  Singleton<T>::object_creator
20 Singleton<T>::create_object;

我们的talk中定义了大概是这样一个 macro      #define   MY_INSTANCE(className)      Singleton<className>::instance();   在每个单例类使用的地方, 如TalkServer,   MY_INSTANCE(TalkServer)就会返回  TalkServer 的唯一引用

以上实现的Singleton是一个类模板,  类模板在程序中任何一个地方被引用的时候, 都会根据模板参数去生成一个类(编译过程中),  根据上面的实现, 应该是相应的 static 成员变量的定义也会加上,  然后static member 的初始化会在 main函数执行之前, 也是就main函数执行之前 我们要使用的单例类已经有了,  被Singleton<T>生成的类所持有着,  以局部静态变量的形式(不是成员),  (member function和global function中的static 变量应该是一样的吧)

在effective中有一条  make sure base classes have virtual destructor  , 一个类若有可能作基类, 其 destructor一定要是 virtual的  在类内部要调用析构(会有这个必要吗) 时, delete this

boost::utility 中 noncopyable 的实现, 在boost namespace 下

1 class noncopyable{
2 protected :
3          noncopyable () {}
4          ~noncoyable () {}
5 private :
6          noncopyable (const noncopyable&);
7          const noncopyable& operator= (const noncopyable&);
8 } 

constructor, destructor为protected,派生类可以实例化,  从noncopyable派生, 则不可被赋值, 不可拷贝  copy constructor和重载的operator= 是不可以被派生类所继承的,好像这是除constructor,destructor外唯一不可被继承的member function

注意后两个函数只被声明了, 没有实现, 这样是可以的, 只有在链接的时候若用到了这个函数,才会去寻找它的定义,生成.o是不会报错的,而如果从noncopyable派生,使用了operator=,在生成.o即编译的时候就会报错了

 

posted on 2012-04-20 20:40  小宇2  阅读(929)  评论(0编辑  收藏  举报

导航