a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 126|回复: 1

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

[复制链接]
发表于 2012-7-31 21:48:08 | 显示全部楼层 |阅读模式
在面向对象的语言里面,出现了类的概念。这是编程 思想 的一种进化。所谓类:是对特定数据的特定操作的集合体。所以说类包含了两个范畴:数据和操作。而C语言中的struct仅仅是数据的集合。  ( Z5 y( d. d6 H. C: j1 S$ z/ A; h
+ [- M) W; U* K7 P4 R
1.实例:下面先从一个小例子看起  - O8 A' f" g+ _1 H

9 [" j' Y) x$ Z& r2 @9 M# Z#ifndef C_Class  4 M/ b& h3 R1 b3 |
#define C_Class struct  6 f  l0 k  n! b8 {
#endif  
; @8 @, d& l. I0 p6 y
2 E' R; w" f; {1 G/ c" O( q$ zC_Class A {  0 d; F% l! M+ w# Z  R8 X+ r
C_Class A *A_this;  - K" g% {& r/ `' d! f
void (*Foo)(C_Class A *A_this);  
3 @6 o. V: W! J" hint a;  
6 Q# m0 Z/ |! b8 J7 L" Lint b;  & z3 T, y' E5 J8 E! J% ?8 b1 b
};  5 r: N& E2 m, H% w

  t( a  q. o$ H3 W2 i" |( y, lC_Class B{ //B继承了A  
6 N' w# E! U! C, y, K* a2 pC_Class B *B_this; //顺序很重要  9 D; }4 z7 M* Y, l1 K9 i* x/ H
void (*Foo)(C_Class B *Bthis); //虚函数  " j- y4 T) n- `( @$ b& @
int a;  3 }. f2 @  B* t5 ~3 D
int b;  8 Z  Y+ c7 _( Q% Q) e6 t( @* k

( `. U( ?0 `1 |* ]# c: ~% Q3 W5 Aint c;  ! O# b3 t3 W: A) B
};  ' ?* u; k7 c9 p- r* x

  j( [2 v' F  _3 {2 Q7 |7 F0 _2 |( E7 Y9 X, t
void B_F2(C_Class B *Bthis)  8 I1 ^( E+ {3 h: u: F" }) U
{  
8 n  y+ ^8 a7 W) {; i# h- hprintf("It is B_Fun ");  
0 q- `8 R$ X# e) q% w8 s: T}  $ A7 [& Z- l& b  H  I' _
9 g( o9 ~1 M0 H+ J: L
void A_Foo(C_Class A *Athis)  - W; n9 B! ]& W6 |9 O4 X" j0 d4 W& [
{  & G* d+ ^' A' Z# x- x
printf("It is A.a=%d ",Athis->a);//或者这里  
- d& r" }0 ~6 [1 T4 y9 D$ I// exit(1);  
; L( [% p% Z' B# M; @// printf("纯虚 不允许执行 ");//或者这里  
5 l$ M4 T# {: n7 U; [& \2 x7 Y}  4 P" A$ l. s# M" I8 g" U% k. C% v
4 L+ ^6 v7 e9 l
void B_Foo(C_Class B *Bthis)  
/ a+ }0 k+ v6 V, q" G2 J$ z{  
: B% f5 y  H: w$ }printf("It is B.c=%d ",Bthis->c);  
9 o5 h2 C5 p" [}  ) ]  G# ]+ D* H4 H
. c9 I; u' |4 x) V  B
void A_Creat(struct A* p)  . E' X: a; f8 r2 x5 Z! L
{  
' e7 d, Y4 |+ c5 `+ q* Up->Foo=A_Foo;  2 D8 _' S) X4 ]  D4 Y' Z1 f
p->a=1;  " \3 o2 O7 l- y% K# F
p->b=2;   9 |" |+ [" v3 R& i* _
p->A_this=p;  
) w( ]1 N9 `' O9 X8 ?% {* l}  2 ~. b8 N, }4 N% D$ \8 E/ K
: I# x3 j6 B& q9 N
; c/ ~4 ?8 c) @3 V- L
void B_Creat(struct B* p)  
! G8 h! q7 h4 e6 |{  
" i7 ]7 D8 f$ c# e& d6 N( zp->Foo=B_Foo;  
1 f/ Z* q' P- d# c& Fp->a=11;  
9 ?% e$ p) ~5 P/ \p->b=12;   
3 g2 f  [' I# t5 `; P5 u& tp->c=13;  
. M; ~# K8 W. T* q9 f0 \# F' q/ pp->B_this=p;  
! {7 ?! l( K2 R1 @; B3 H  D6 h1 e: [}  
. u2 e& U+ O) }  _6 X& @3 G: H' a. I1 p) U+ T+ t9 C

- I: c5 y% ], B% y9 Aint main(int argc, char* argv[])  
* @0 o, H" i( \# |, }1 `2 d{  
2 y; N+ W0 @: g7 G" \) _. gC_Class A *ma,a;  
" d1 e* q. \, L' k3 P" K& mC_Class B *mb,b;  
9 |" y- J; \3 ?
8 A, d8 \2 @0 A  z# qA_Creat(&a);//实例化  
& q7 V+ a8 n7 B9 VB_Creat(&b);  
9 l/ V  o6 [7 t/ Y1 a" ?3 p9 v" a7 b2 j# s; {
mb=&b;  
. Y& l( S1 F4 H6 }: Xma=&a;  
: ?$ y0 O0 e8 V4 F) \0 y0 m. `, G  W+ j& S3 f1 i' n  Z/ @
ma=(C_Class A*)mb;//引入多态指针  & N; {$ z1 J' |0 ]
printf("%d ",ma->a);//可惜的就是 函数变量没有private  
' o2 R6 k6 q! r4 t* y* Wma->Foo(ma);//多态  
- n$ T8 d7 k0 ua.Foo(&a);//不是多态了  & O4 e9 [+ x" k- ?$ p/ Z
B_F2(&b);//成员函数,因为效率问题不使用函数指针  
" G, H7 q" y1 o, creturn 0;  
$ c2 [! Y; m) U% |}  ' p  B7 a0 B1 k
输出结果:  
' [) q5 {, x7 q/ l: i- I1 x11  
, d7 X; u/ a/ S8 uIt is B.c=13  0 ?) c# P6 u2 G& Y' o3 d
It is A.a=1  3 c) G# h( {  m! j; a6 m" j/ A$ a8 `- O
It is B_Fun
回复

使用道具 举报

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

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

2.类模拟解说:  
8 l# _+ u3 u% C  s+ m  我在网上看见过一篇文章讲述了类似的思想(据说C++编程思想上有更加详细的解说,可惜我没空看这个了,如果有知道的人说一说吧)。但是就象C++之父说的:“C++和C是两种语言”。所以不要被他们在语法上的类似就混淆使用,那样有可能会导致一些不可预料的事情发生。  ' b- O* w( V( D- ]
其实我很同意这样的观点,本文的目的也不是想用C模拟C++,用一个语言去模拟另外一个语言是完全没有意义的。我的目的是想解决C语言中,整体框架结构过于分散、以及数据和函数脱节的问题。  2 l! }& T; k2 Z. d" X
  C语言的一大问题是结构松散,虽然现在好的大型程序都基本上按照一个功能一个文件的设计方式,但是无法做到更小的颗粒化――原因就在于它的数据和函数的脱节。类和普通的函数集合的最大区别就在于这里。类可以实例化,这样相同的函数就可以对应不同的实例化类的变量。  2 x" I4 o" N+ s+ b% K, ~+ K
自然语言的一个特点是概括:比如说表。可以说手表,钟表,秒表等等,这样的描述用面向对象的语言可以说是抽象(继承和多态)。但是我们更要注意到,即使对应于手表这个种类,还是有表链的长度,表盘的颜色等等细节属性,这样细微的属性如果还用抽象,就无法避免类膨胀的问题。所以说类用成员变量来描述这样的属性。这样实例并初始化不同的类,就描述了不同属性的对象。  
6 u. e1 J* U) m( p/ P) ]  但是在C语言中,这样做是不可能的(至少语言本身不提供这样的功能)。C语言中,如果各个函数要共享一个变量,必须使用全局变量(一个文件内)。但是全局变量不能再次实例化了。所以通常的办法是定义一个数组。以往C语言在处理这样的问题的时候通常的办法就是这样,比如说socket的号,handel等等其实都是数组的下标。(不同的连接对应不同的号,不同的窗口对应不同的handel,其实这和不同的类有不同的成员变量是一个意思)  
; }3 A, L& |$ E# T+ t7 @5 @/ B个人认为:两种形式(数组和模拟类)并无本质的区别(如果不考虑虚函数的应用的话),它们的唯一区别是:数组的办法将空间 申请 放在了“模块”内,而类模拟的办法将空间申请留给了外部,可以说就这一点上,类模拟更加灵活。  . [& U5 U0 r! z+ h' O4 Y

. V9 G0 ^/ y- t+ D3 U! R* Q3.其他的话:  ) L8 y% o# D8 s% h, G; j
  我的上述思想还是很不成熟的,我的目的是想让C语言编程者能够享受面向对象编程的更多乐趣。我们仅仅面对的是浩瀚的“黑箱”,我们的工作是堆砌代码,而且如果要更改代码功能的时候,仅仅换一个黑箱就可以了。  5 ~# O' Y% c; `% q/ L& m
  而更大的目的是促使这样的黑箱的产生。或许有一天,一种效率很好,结构很好的语言将会出现。那个时候编程是不是就会象说话一样容易了呢?  来</p>
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-23 02:00 , Processed in 0.202628 second(s), 23 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

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