a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 128|回复: 1

[C语言] 关于C语言中的类模拟和多态,继承

[复制链接]
发表于 2012-7-31 21:48:08 | 显示全部楼层 |阅读模式
在面向对象的语言里面,出现了类的概念。这是编程 思想 的一种进化。所谓类:是对特定数据的特定操作的集合体。所以说类包含了两个范畴:数据和操作。而C语言中的struct仅仅是数据的集合。  
$ i6 f: ^$ ]6 d9 E8 d4 N6 o+ Z. g$ L2 Z1 [5 Y7 y3 w% B7 K# C
1.实例:下面先从一个小例子看起  1 y% B4 `  f: t( i2 {+ s/ i

$ m) u; c+ M9 b7 o  D#ifndef C_Class  4 Q; R0 w6 k$ r
#define C_Class struct  
/ w5 X$ b  E+ ^#endif  
/ r" M  @' b0 W3 e( K% o+ M+ l3 U' k% A8 q- \! N1 t$ M
C_Class A {  
- Q* _; O" w8 E; T6 ~% WC_Class A *A_this;  
2 f9 O! w! s4 T/ U# bvoid (*Foo)(C_Class A *A_this);  
" M8 K6 R% a( ?% N3 @! Z. a& m0 B) cint a;  
! Z( _: t$ @2 L) Y7 gint b;  
; M, x' O$ C. \};  2 K8 M. l5 [! {+ @9 ?! I
- [; U2 x+ Q4 }
C_Class B{ //B继承了A  
* N7 r& j9 p. E# B) ?1 xC_Class B *B_this; //顺序很重要  ' s! p+ T( D& f  D7 A7 M' W
void (*Foo)(C_Class B *Bthis); //虚函数  " c0 t. `- Q4 ?! t* k
int a;  6 H  ]) g( E$ F
int b;  
1 z6 @/ A( ?) Q: A# i; F
- y& W& a$ ?# b9 Rint c;  
2 I" b, U5 ]$ @' y, \) o5 s};  
$ a2 M# }! T( q& p& ~/ ]2 ~& X
( h3 H2 q" Q' S& J" D1 R( C7 Z
" b, ~- ?3 o- e" o1 b& W2 O- Yvoid B_F2(C_Class B *Bthis)  
% w4 g  z: d3 L- `+ z{  
! L* ~% Z8 z% V2 Fprintf("It is B_Fun ");  
1 p9 g+ ~- }' \2 U0 J- }2 p}  
9 i# P  A$ ^( D% Z
7 ], r: z4 W' A2 P# ^void A_Foo(C_Class A *Athis)  
3 |) `  t4 @& F3 P; A+ H: y0 _{  3 ^( [  m8 k9 w+ Y$ b; [9 i
printf("It is A.a=%d ",Athis->a);//或者这里  
" E0 [( t6 n/ ~* s1 M// exit(1);  2 T0 Y! Z" P$ `( l
// printf("纯虚 不允许执行 ");//或者这里  + u4 |" S" o( o: D2 V. J1 M
}  
6 A. m6 I7 U  ]) k" c4 O' X
( a( K/ _0 e9 O- M- v& cvoid B_Foo(C_Class B *Bthis)  
6 O8 _  ~4 ?; V4 k{  1 H4 |; t; m$ f3 b6 N
printf("It is B.c=%d ",Bthis->c);  . a& P, W' w% v. ?
}  
! l; T. |% Y% F; ]! D/ L
* E/ ]8 n/ w; U; v/ D3 @void A_Creat(struct A* p)  
# D) J7 n: h4 e2 M  B# J4 o{  
9 K. q/ T; y! L3 J. k+ e4 q8 K4 Zp->Foo=A_Foo;  1 n: p8 T" \/ P: L
p->a=1;  1 Q' W# L% @6 i9 E+ t. m7 h
p->b=2;   $ r" e0 M2 m7 P% K
p->A_this=p;  
6 N' a, a6 J) T}  2 F* h3 g' Q3 A: ~) \7 F5 ^5 F

: f7 o5 ~+ a& Z6 `- `5 d3 C! @& L! r7 r/ B
void B_Creat(struct B* p)  
2 k# b* l$ x% N9 u{  
: q7 c( ?+ D3 Y, X0 H' D, ep->Foo=B_Foo;  ' i% z7 r6 g& a0 C' D! I7 v
p->a=11;    v2 q+ W& `/ O/ O6 U) e
p->b=12;   
4 Z- n+ H( _0 E  Ap->c=13;  
8 i( o4 R7 }6 |$ U" Wp->B_this=p;  
% T( I6 |8 {  t9 P5 z4 I9 ^- m  g1 \}  
8 ]  \4 @0 m. T/ Y
& B. I& ?4 o# P9 {5 e8 a' D. Y0 J
0 W' g$ \6 f: r0 x, ^/ ]. t4 F+ p7 c! Sint main(int argc, char* argv[])  1 U- i& S/ t+ n8 I
{  
; S$ h* {0 D. [' a" Z; e( ZC_Class A *ma,a;  
0 k1 G+ F$ D  a8 y" R7 ?+ Z6 lC_Class B *mb,b;  
6 z4 p' u6 N4 x$ v, p- y9 }8 |$ Y/ w( _; K
A_Creat(&a);//实例化  $ F/ u$ u! q0 m" t% p+ u( r
B_Creat(&b);  
' X4 e8 m) t3 p- T- }  L9 P$ g0 H8 R& D; L" q, d( Q" t
mb=&b;  
) O. K) P# q# E* V9 f! k* Ima=&a;  
2 ?/ C8 J) y: B; \5 K
' j" w. }. Z' Gma=(C_Class A*)mb;//引入多态指针  
5 z/ l4 @2 \3 x. n/ S0 j6 B& Gprintf("%d ",ma->a);//可惜的就是 函数变量没有private  
. `0 ]; p5 `! S+ ?- ]ma->Foo(ma);//多态  
/ J: k4 s! [3 u8 W0 ua.Foo(&a);//不是多态了  
) I) @: X( n! K) iB_F2(&b);//成员函数,因为效率问题不使用函数指针  ' D' e- q3 s8 C
return 0;  5 p1 W( _2 U3 J; l
}  
, I; a, [2 E, S. K" T- s8 d/ |2 ^输出结果:  6 @$ b5 p2 D( P# U
11  : c* O( _$ Z& U% p4 v  g1 d
It is B.c=13  
2 o: P- H+ ?. k2 H( L* p; [: d- TIt is A.a=1  * a1 M, K5 C! w, ]5 v
It is B_Fun
回复

使用道具 举报

 楼主| 发表于 2012-7-31 21:48:09 | 显示全部楼层

关于C语言中的类模拟和多态,继承

2.类模拟解说:  
/ K& _' V- P" F' q6 M+ m  我在网上看见过一篇文章讲述了类似的思想(据说C++编程思想上有更加详细的解说,可惜我没空看这个了,如果有知道的人说一说吧)。但是就象C++之父说的:“C++和C是两种语言”。所以不要被他们在语法上的类似就混淆使用,那样有可能会导致一些不可预料的事情发生。  ; q. f4 n  O: u5 J8 [
其实我很同意这样的观点,本文的目的也不是想用C模拟C++,用一个语言去模拟另外一个语言是完全没有意义的。我的目的是想解决C语言中,整体框架结构过于分散、以及数据和函数脱节的问题。  0 T1 F) t  y+ o/ m; I" S
  C语言的一大问题是结构松散,虽然现在好的大型程序都基本上按照一个功能一个文件的设计方式,但是无法做到更小的颗粒化――原因就在于它的数据和函数的脱节。类和普通的函数集合的最大区别就在于这里。类可以实例化,这样相同的函数就可以对应不同的实例化类的变量。  : k3 L8 b5 v2 v- D
自然语言的一个特点是概括:比如说表。可以说手表,钟表,秒表等等,这样的描述用面向对象的语言可以说是抽象(继承和多态)。但是我们更要注意到,即使对应于手表这个种类,还是有表链的长度,表盘的颜色等等细节属性,这样细微的属性如果还用抽象,就无法避免类膨胀的问题。所以说类用成员变量来描述这样的属性。这样实例并初始化不同的类,就描述了不同属性的对象。  
0 S8 g# P4 C" ?6 y' s, p; c, ?6 j- ]  但是在C语言中,这样做是不可能的(至少语言本身不提供这样的功能)。C语言中,如果各个函数要共享一个变量,必须使用全局变量(一个文件内)。但是全局变量不能再次实例化了。所以通常的办法是定义一个数组。以往C语言在处理这样的问题的时候通常的办法就是这样,比如说socket的号,handel等等其实都是数组的下标。(不同的连接对应不同的号,不同的窗口对应不同的handel,其实这和不同的类有不同的成员变量是一个意思)  & X) v/ M2 N! r2 f; Y% a
个人认为:两种形式(数组和模拟类)并无本质的区别(如果不考虑虚函数的应用的话),它们的唯一区别是:数组的办法将空间 申请 放在了“模块”内,而类模拟的办法将空间申请留给了外部,可以说就这一点上,类模拟更加灵活。  / V: j. O* `/ U! r3 ^% H
6 \2 j1 t4 P6 o& I  n3 o; I
3.其他的话:  
* z# z  f  j  H, s( C, V7 S3 N  我的上述思想还是很不成熟的,我的目的是想让C语言编程者能够享受面向对象编程的更多乐趣。我们仅仅面对的是浩瀚的“黑箱”,我们的工作是堆砌代码,而且如果要更改代码功能的时候,仅仅换一个黑箱就可以了。  
: I2 g% l4 b8 \- t) v/ X  而更大的目的是促使这样的黑箱的产生。或许有一天,一种效率很好,结构很好的语言将会出现。那个时候编程是不是就会象说话一样容易了呢?  来</p>
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Woexam.Com ( 湘ICP备18023104号 )

GMT+8, 2024-6-16 11:07 , Processed in 0.196688 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表