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

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

51Testing软件测试网VUVnr7Z*@nl

  一、分析51Testing软件测试网 ?&{3bv+U

7Y| V@6sG|0  在Java中定义了关键字final,被final修饰的类不能被继承。但在C++中没有final这个关键字。

^%D,['{Qc_/h@\0 51Testing软件测试网V2UtaL#Y,e%@:vY

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

51Testing软件测试网5vO3K#M0~E%Q

  可是这个类的构造函数和析构函数都是私有函数了,我们怎样才能得到该类的实例呢?51Testing软件测试网+mp4R1EKS8}4h

*E8?c-O+f-I.A i0  通过定义静态来创建和释放类的实例。

F4U.lP)F;PCn&p-p{0a0

SOVK.T@mWb6Ky!w0  二、实现51Testing软件测试网d8T:b3T)x |YR8@&P8e.L

51Testing软件测试网 w}*m5}!d7_!f9{:F

  下面是一个单利模式的实现

&]4D+v$u)l4E9xf0

Q-CYkK*L"f0 51Testing软件测试网)P9yDqZ#Cy3~!C

$x1N6Qva/Y0#include <iostream>  
vS6mu$?7k0using namespace std;   51Testing软件测试网|dy"f-t [.h#Y xJ*}7X
class Singleton
@^X;j#}k5fWv;Y0{51Testing软件测试网:b4_Mv%mxI C'J
private:
~;`P n3p_0      Singleton(); 51Testing软件测试网+m2e`X+|h4ji1}2XY
      ~Singleton();// {}
nPp8D X0      static Singleton *instance;
Rf(O^8c,~?O^0public:
.]%th^%Thi0      static Singleton* GetInstance() 51Testing软件测试网l7r%p9H7O ?_
      {51Testing软件测试网5m7v,U&y0K w
       
D$rj-F L0m6]"z0            if(instance == NULL)
?#SB ig,W0    {
%O;\2i/pDj t a D0      instance = new Singleton();51Testing软件测试网4h7rIbj
    }51Testing软件测试网 ]"k-ry"ap
            return instance;
? i'l1D%?{.|k;Y0      }
7l"W7E*N a7c5T O0      static void DeleteInstance()
!Op#nq9d6J6p7c~0      {
&?8u7CaYQ0            if(instance != NULL)51Testing软件测试网G rF nD d(M
    {
d$N o5i5N ]/c;JgQL0      delete instance;
{Cyg(@j`%qGT0    }
2adh3]C,w9P4G0      }

{"ug!VZwk6H0 51Testing软件测试网V G x4mL8`~.x

};51Testing软件测试网PH,d1C/T$b$o/O kE
Singleton* Singleton::instance=NULL;//一定要初始化(由于不能在方法体内部初始化,所以就放到外部)

'y/V!_Y8v0

`'Z_x&_/~i0int main()
!\T5xMl0{51Testing软件测试网!mvv-_(Hc+iK
 
#W![,`Aep0}
1ra Z:@;e p1a3X0
51Testing软件测试网HVb qQ

51Testing软件测试网6Iz6} l EI}'B

  这个类是不能被继承,但在总觉得它和一般的类有些不一样,使用起来也有点不方便。比如,我们只能得到位于堆上的实例,而得不到位于栈上实例。

}[d(\9|6Qe0

o-uvSqQr0  能不能实现一个和一般类除了不能被继承之外其他用法都一样的类呢?办法总是有的,不过需要一些技巧。请看如下代码:51Testing软件测试网.O!CPi;T$V5zQCX`

51Testing软件测试网x;S)p^$r sK,g)E

^!`5a8j)^0
51Testing软件测试网 rM#r#~^7yvs\H

class MakeFinal
)Y1a,_k1KT.^0{
f!h I Bo$d0      friend FinalClass2;51Testing软件测试网ry,o |(Ua^,A
private:
'@3Li9|D2R.y$B0      MakeFinal() {}
9WN8T.N3b*imB7A0      ~MakeFinal() {}51Testing软件测试网"G+Ou*Kja DR
};
51Testing软件测试网 leRR0gw tc

51Testing软件测试网0uoDwUc fQW

class FinalClass2 : virtual public MakeFinal51Testing软件测试网lnv3N4s dBP
{51Testing软件测试网8D^@ I F$P
public:
51Testing软件测试网#G1Q\7F8R }gI!i

g i!A^9If7IG0      FinalClass2() {}51Testing软件测试网M3|2G:_fl @
      ~FinalClass2() {}
XE0{mf)Bp'Q o0};

vQ]ub]0

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

b9G}:uC0 51Testing软件测试网2Vu`(R8`)Q&Qh

  但当我们试图从FinalClass2继承一个类并创建它的实例时,却不同通过编译。

\&}+@$GA+`7v}-e0q-j0

n t"P)O-@b0k5} l0 51Testing软件测试网g_,G7Z,h9? j E|

,b%AzFy B M0class Try : public FinalClass251Testing软件测试网#[+@RP"AW P
{
5ky~/|` h1s,k)~0public:51Testing软件测试网\B:_!f;}
      Try() {}51Testing软件测试网f+F]D-I'V {R$z l
      ~Try() {}51Testing软件测试网}v3Cj2pX I:h[
};

jf"I/[I2Y1n0V0 51Testing软件测试网;v5Cu6}2q3K

Try temp;

iav6BZ.m c?\0E.n0

E Z7E dW-x)t1sFF0  由于类FinalClass2是从类MakeFinal 虚继承过来的,在调用Try的构造函数的时候,会直接跳过FinalClass2而直接调用MakeFinal的构造函数。非常遗憾的是,Try不是MakeFinal的友元,因此不能调用其私有的构造函数。51Testing软件测试网i0E6eS$j

51Testing软件测试网 i){RK)eJx_3Mf

  基于上面的分析,试图从FinalClass2继承的类,一旦实例化,都会导致编译错误,因此是FinalClass2不能被继承。这就满足了我们设计要求。

C:E#mM MT0

TAG:

 

评分:0

我来说两句

Open Toolbar