用C++编写不能被继承的类

上一篇 / 下一篇  2012-08-27 11:00:08 / 个人分类:C++

51Testing软件测试网.D}D9w8}g

  一、分析

~+J/]^/S Z(goX!e0 51Testing软件测试网{KN]S%J c#fY!X

  在Java中定义了关键字final,被final修饰的类不能被继承。但在C++中没有final这个关键字。

%me`^ij1`[X\p0 51Testing软件测试网2jigQWK(^

  首先想到的是在C++ 中,子类的构造函数会自动调用父类的构造函数。同样,子类的析构函数也会自动调用父类的析构函数。要想一个类不能被继承,我们只要把它的构造函数和析构函 数都定义为私有函数。那么当一个类试图从它那继承的时候,必然会由于试图调用构造函数、析构函数而导致编译错误。

)u6EW$I8H0 51Testing软件测试网]6e8u.n.Hy]$F

  可是这个类的构造函数和析构函数都是私有函数了,我们怎样才能得到该类的实例呢?

'V a0h3@U5P z]0 51Testing软件测试网%O7i[6V5T i3e

  通过定义静态来创建和释放类的实例。51Testing软件测试网^d,U&]{s)g

WoX$w.Pd0  二、实现51Testing软件测试网I1fD5o6otH

51Testing软件测试网DcwFH3c A'[ C

  下面是一个单利模式的实现51Testing软件测试网_ bJXQTd*Y

51Testing软件测试网 v)Yk5f Ur.B)_6f

51Testing软件测试网8H%M-wV1CM(J:Y

51Testing软件测试网J'h-aO3] ^D

#include <iostream>  
X(M0A%Q&c!S7D,w0using namespace std;  
Lw(m8v!Z*hP.el2@;~ T,J0class Singleton
.yy~d\^]*bX@Y4k0{
M:{V*m"F3u"@0private:
i6Oh%vn!e4w0      Singleton();
C uq bM)C1{,ZA0      ~Singleton();// {}51Testing软件测试网-QO9g3t(W`eb'S
      static Singleton *instance;
r5bj*_h&V_0public:
:r|7@/y8H4`0      static Singleton* GetInstance()
#w q9e W [2t0      {
$D,e GQf0       
}2Fl,|JX^0            if(instance == NULL)51Testing软件测试网,Tb$A O]_Z1| z:}zl-iz
    {51Testing软件测试网I5]i]vR3q,Pc$g
      instance = new Singleton();
aF9R#pL\ A0    }51Testing软件测试网nP/F2nC T3eG
            return instance;
*U1Bb$QR"m4o f0      } 51Testing软件测试网A/h'?@{ N#_b4K} m`
      static void DeleteInstance()
fY(kvz0O3F-Y0      {
,c Dx:D.g(b6b2F0            if(instance != NULL)
@_`I!U`m V GLA0    {51Testing软件测试网2D H'xl C+A m
      delete instance;
A&d~;_of4L;}3f1Ur-Q0    }
\'Zv a0`~;~:b0      }
51Testing软件测试网 r }h:lv9c

51Testing软件测试网j gE u r z

};
9a T8kIdQ#om]0Singleton* Singleton::instance=NULL;//一定要初始化(由于不能在方法体内部初始化,所以就放到外部)
51Testing软件测试网+tz`kb3k:g;V6d0Q0r4}

}5v3_"}%E0int main()51Testing软件测试网C%A P(^9lc'\ xT
{
Y-L9W \0g%rsp8M0 
@N$Tt)K1o!Y0} 51Testing软件测试网 R:I Rd(cB$L&T&?m

T(qgVo v,k1t051Testing软件测试网4k;To$RYe0Vj@-~

  这个类是不能被继承,但在总觉得它和一般的类有些不一样,使用起来也有点不方便。比如,我们只能得到位于堆上的实例,而得不到位于栈上实例。51Testing软件测试网rw,\n_4~u

51Testing软件测试网ei8cEdzue A

  能不能实现一个和一般类除了不能被继承之外其他用法都一样的类呢?办法总是有的,不过需要一些技巧。请看如下代码:

e!tDLj(F0

|/q*H`~3kl0

6L+i.uA G U'N0
51Testing软件测试网Z,f ~+v:@3gZ&g0T

class MakeFinal51Testing软件测试网x/q_"gSd7r
{
'VlK4Z$OH)q0      friend FinalClass2;
$^\](B)eNo0private:
7K'R J f%w p7kH0      MakeFinal() {}
:y2hP t/z0      ~MakeFinal() {}
*k jpR4@Z)E!\q`0};

#U'D0~K:o*I0 51Testing软件测试网g i9y+^0~#mG*jM"L/C

class FinalClass2 : virtual public MakeFinal51Testing软件测试网/Y|~3M,AQS
{51Testing软件测试网)e&m_-rs1X;^)x |'jW
public:
51Testing软件测试网BaTHS m @h

51Testing软件测试网 RlT%Ip Y"u(Uo:p

      FinalClass2() {}
gQ_N\ew]v0      ~FinalClass2() {}
{ Z1I+O p&YC0};
51Testing软件测试网6G.SC1mS@D$U

-A)C3aDJW4y0  这个类使用起来和一般的类没有区别,可以在栈上、也可以在堆上创建实例。尽管类MakeFinal的构造函数和析构函数都是私有的,但由于类 FinalClass2是它的友元函数,因此在FinalClass2中调用MakeFinal<FinalClass2>的构造函数和析构 函数都不会造成编译错误。

5c.A9R{7G0

D`XM)C:Y0  但当我们试图从FinalClass2继承一个类并创建它的实例时,却不同通过编译。51Testing软件测试网 S-rKo7R

4bC)W*tKg4y;E0 51Testing软件测试网^v9HX^4\)g

51Testing软件测试网_np(Fp$i9V

class Try : public FinalClass2
gF{+N'V \f7E5f0{51Testing软件测试网5l Rg u P
public:
(B,h3J"@1I0      Try() {}
(I(e"s:L I:BC sp Ebk~9D0      ~Try() {}51Testing软件测试网'hG^'Q^4THN%vV
};
51Testing软件测试网 m kCN+`-T$N_n}%G

n-I8KZY0Try temp;

7\0D a(n)^0
51Testing软件测试网;N)[R:V] A0y

  由于类FinalClass2是从类MakeFinal 虚继承过来的,在调用Try的构造函数的时候,会直接跳过FinalClass2而直接调用MakeFinal的构造函数。非常遗憾的是,Try不是MakeFinal的友元,因此不能调用其私有的构造函数。

:q^Mt{I0 51Testing软件测试网uDX1E4Bch

  基于上面的分析,试图从FinalClass2继承的类,一旦实例化,都会导致编译错误,因此是FinalClass2不能被继承。这就满足了我们设计要求。51Testing软件测试网3ji"u5jI'QF


TAG:

 

评分:0

我来说两句

Open Toolbar