在c++中如何阻止类被继承

这个话题是源自于一个面试题,我在网上查了一下有不少这方面的解说!我自己整理了一下,选择了一个自认为是最优方案!
我们从最简单的开始:
首先,大家都知道要阻止类被实例化,可以通过使用private or protected 关键字来声明默认构造函数。那么在阻止类被继承的时候,我们需要用到这个技巧。其次,阻止类被继承还需要使用private来控制继承的基类。

None.gif namespace  SamplePrivate
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
InBlock.gif#ifdef NDEBUG
InBlock.gif
InBlock.gif    
class Sealed
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
protected:
ExpandedSubBlockStart.gifContractedSubBlock.gif            Sealed() 
dot.gif{};
InBlock.gif
InBlock.gif            friend 
class SampleSealedClass; // 设置友类,以便访问Sealed的构造函数
ExpandedSubBlockEnd.gif
    }
;
InBlock.gif
InBlock.gif    
class SampleSealedClass : private virtual Sealed
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockEnd.gif    }
;
InBlock.gif
InBlock.gif    
InBlock.gif
#else
ExpandedSubBlockStart.gifContractedSubBlock.gif    
class SampleSealedClass dot.gif{}
InBlock.gif
#endif
InBlock.gif
ExpandedBlockEnd.gif}
这样我们就可以实例化SampleSealedClass,并且还不用担心被继承了。不过还是要解释一下为什么阻止了继承?
当我们写出下面的代码时,编译器在编译过程中做了什么呢?
None.gif class  subclass :  public  SampleSealedClass
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedBlockEnd.gif};
首先,当你在实例化subclass的时候,会先调用SampleSealedClass的构造函数,而在这之前会调用Sealed类的默认构造函数,但是我们发现Sealed是不能被实例化的,并且通过private virtual的继承只能被SampleSealedClass调用,因此这很好的阻止了类被继承。但是这里我们只能完成一个类被不被继承,那么是否有更好的方法来实现阻止任意类被继承呢?
那就需要用到模板了:
None.gif #ifdef NDEBUG
None.gif
None.gif
namespace  SealedClasses
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
class Sealed
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
protected:
ExpandedSubBlockStart.gifContractedSubBlock.gif            Sealed() 
dot.gif{}
ExpandedSubBlockEnd.gif    }
;
InBlock.gif
InBlock.gif    template
<class T> class TypeWapper 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
public:
InBlock.gif            typedef T type;
ExpandedSubBlockEnd.gif    }
;
ExpandedBlockEnd.gif}

None.gif
None.giftemplate
< typename T >   class  BaseSealed :  private   virtual  SealedClasses::Sealed
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    friend 
class SealedClasses::TypeWapper<T>::type; 
ExpandedBlockEnd.gif}
;
None.gif
None.gif
#else
None.gif
None.giftemplate
< typename T >   class  BaseSealed
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedBlockEnd.gif}
;
None.gif
None.gif
None.gif
#endif
这里的TypeWapper主要是将外部类型传递到SealedClasses的,从而能得到访问Sealed构造函数的能力。不过这段代码在GCC4.0中通过编译,而在vs2008中不能通过。可以向下面这样来引用:
None.gif class  subclass : BaseSealed < subclass >
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public:
ExpandedSubBlockStart.gifContractedSubBlock.gif        subclass() 
dot.gif{ cout << "subclass" << endl; }
ExpandedBlockEnd.gif}
;
None.gif
None.gif
//  下面这个会编译失败
None.gif
class  ssubclass :  public  subclass
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public:
ExpandedSubBlockStart.gifContractedSubBlock.gif        ssubclass() 
dot.gif{ cout << "ssubclass" << endl; }
ExpandedBlockEnd.gif}
;

转载于:https://www.cnblogs.com/moonz-wu/archive/2008/05/07/1186065.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值