禁止堆对象

来源:互联网 发布:云南大学软件学院导师 编辑:程序博客网 时间:2024/05/17 06:15
例如,如果你想不想让用户在堆中建立UPNumber

对象,你可以这样编写: 


class UPNumber { 
private: 
  static void *operator new(size_t size); 
  static void operator delete(void *ptr); 
  ... 

}; 


现在用户仅仅可以做允许它们做的事情: 
UPNumber n1;                         // okay 
static UPNumber n2;                  // also okay 
UPNumber *p = new UPNumber;          // error! attempt to call 

                                     // private operator new 


有趣的是,把operator new声明为private经常会阻碍UPNumber对象做为一个位于堆
中的派生类对象的基类被实例化。因为operator new和operator delete是自动继承的,如果operator new和operator delete没有在派生类中被声明为public(进行改写,overwrite),它们就会继承基类中private的版本,如下所示: 


class UPNumber { ... };             // 同上 
class NonNegativeUPNumber:          //假设这个类 
  public UPNumber {                 //没有声明operator new 
  ... 
}; 


NonNegativeUPNumber n1;             // 正确 
static NonNegativeUPNumber n2;      // 也正确 
NonNegativeUPNumber *p =            // 错误! 试图调用 
  new NonNegativeUPNumber;          // private operator new 

如果派生类声明它自己的operator new, 当在堆中分配派生对象时, 就会调用这个函数,于是得另找一种不同的方法来防止UPNumber基类的分配问题。UPNumber的operator new是private这一点,不会对包含UPNumber成员对象的对象的分配产生任何影响: 
class Asset { 
public: 
  Asset(int initValue); 
  ... 
private: 
  UPNumber value; 
}; 


Asset *pa = new Asset(100);          // 正确, 调用 
                                     // Asset::operator new 或 
                                     // ::operator new, 不是 
                                     // UPNumber::operator new 

0 0