分享

glib实践篇:父类与子类

 quandsu 2017-01-20

前言:

  众所周知,C语言是一门面向过程的语言,但是不代表就得跟面向对象完全绝缘,在C语言库glib中有gobject那么一套面向对象的机制,基于C语言的面向对象设计便是基于该实现机制。

  今天所要实践的便是面向对象的一个重要特征:抽象与继承

  笔者的水平有限,如果文章有什么错误的地方还望指出。

1、设计说明

  开发语言:C语言

  基础库:glib

  设计目的:简要设计类来实现抽象与继承

2、由几个有相同属性或操作的类抽象出一个父类。

  这里简单使用gobject的一套设计模板,细节部分不做说明,有研究兴趣的读者可以研究一下。

  父类:base(该类由base.h和base.c共同组成)

  base.h

复制代码
  
复制代码

  子类1:(由文件subbase1.h和subbase.c组成)

  subbase1.h

复制代码
 1 #ifndef __SUBBASE1_H__
 2 #define __SUBBASE1_H__
 3 
 4 #include 
 5 #include 
 6 #include <>object.h>
 7 #include"base.h"
 8 G_BEGIN_DECLS
 9 
10 #define SUBBASE1_TYPE                    (subbase1_get_type ())//该对象的类型
11 #define SUBBASE1(o)                       (G_TYPE_CHECK_INSTANCE_CAST ((o), SUBBASE1_TYPE, Subbase1))//类型转换,转换为该对象的类型
12 #define SUBBASE1_CLASS(k)                 (G_TYPE_CHECK_CLASS_CAST((k), SUBBASE1_TYPE, Subbase1Class))
13 #define IS_SUBBASE1(o)                    (G_TYPE_CHECK_INSTANCE_TYPE ((o), SUBBASE1_TYPE))
14 #define IS_SUBBASE1_CLASS(k)              (G_TYPE_CHECK_CLASS_TYPE ((k), SUBBASE1_TYPE))
15 #define SUBBASE1_GET_CLASS(o)             (G_TYPE_INSTANCE_GET_CLASS ((o), SUBBASE1_TYPE, Subbase1Class))
16 #define SUBBASE1_CAST(obj)              ((Subbase1*)(obj))
17 
18 
19 typedef struct _Subbase1        Subbase1;
20 typedef struct _Subbase1Class   Subbase1Class;
21 typedef struct _Subbase1Private Subbase1Private;
22 
23 
24 struct _Subbase1
25 {
26     Base    parent;
27 };
28 
29 struct _Subbase1Class    
30 {
31     BaseClass    parentclass;
32 };
33 
34 GType                 subbase1_get_type  (void);
35 Subbase1*                     subbase1_new(void);
36 void                    subbase1_sing_song(Subbase1    *self,char *song);
37 
38 G_END_DECLS
39 #endif /* ABSTRACTMODEL_H_ */
复制代码

  subbase1.c

复制代码
 1 #include "subbase1.h"
 2 #include <string.h>
 3 
 4 //子类的宏定义,继承父类类型
 5 G_DEFINE_TYPE(Subbase1, subbase1, BASE_TYPE);
 6 
 7 #define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SUBBASE1_TYPE, Subbase1))
 8 
 9 struct _Subbase1Private
10 {
11 };
12 
13 static void dispose_od(GObject *object);
14 static void finalize_od(GObject *object);
15 static char *getSkill_od(Base *self);
16 static void    showKill_od(Base *self);
17 static void subbase1_class_init(Subbase1Class *klass)
18 {
19     GObjectClass *object_class = G_OBJECT_CLASS(klass);
20     g_type_class_add_private(klass, sizeof(Subbase1Private));
21     object_class->dispose = dispose_od;
22     object_class->finalize = finalize_od;
23     BaseClass *baseClass = BASE_CLASS(klass);
24     baseClass->getSkill =getSkill_od;
25     baseClass->showKill = showKill_od;
26 
27 }
28 
29 static void subbase1_init(Subbase1 *self)
30 {
31     Subbase1Private *priv = GET_PRIVATE(self);
32 }
33 static void dispose_od(GObject *object)
34 {
35     Subbase1 *self = SUBBASE1(object);
36     Subbase1Private *priv = GET_PRIVATE(self);
37 
38     G_OBJECT_CLASS(subbase1_parent_class)->dispose(object);
39 }
40 
41 static void finalize_od(GObject *object)
42 {
43     Subbase1 *self = SUBBASE1(object);
44     Subbase1Private *priv = GET_PRIVATE(self);
45 
46     G_OBJECT_CLASS(subbase1_parent_class)->finalize(object);
47 }
48 static char *getSkill_od(Base *self)
49 {
50     return "sing";
51 }
52 static void    showKill_od(Base *self)
53 {
54     g_print("I singing!\n");
55 }
56 
57 Subbase1*         subbase1_new(void)
58 {
59     Subbase1 *res = g_object_new(SUBBASE1_TYPE,NULL);
60     return res;
61 
62 }
63 void    subbase1_sing_song(Subbase1    *self,char *song)
64 {
65     g_print("I singing a song for name is %s!\n",song);
66 }
复制代码

  子类2:(由subbase2.h和subbase2.c文件组成)

  subbase2.h

复制代码
 1 #ifndef __SUBBASE2_H__
 2 #define __SUBBASE2_H__
 3 
 4 #include 
 5 #include 
 6 #include <>object.h>
 7 #include"base.h"
 8 G_BEGIN_DECLS
 9 
10 #define SUBBASE2_TYPE                    (subbase2_get_type ())//该对象的类型
11 #define SUBBASE2(o)                       (G_TYPE_CHECK_INSTANCE_CAST ((o), SUBBASE2_TYPE, Subbase2))//类型转换,转换为该对象的类型
12 #define SUBBASE2_CLASS(k)                 (G_TYPE_CHECK_CLASS_CAST((k), SUBBASE2_TYPE, Subbase2Class))
13 #define IS_SUBBASE2(o)                    (G_TYPE_CHECK_INSTANCE_TYPE ((o), SUBBASE2_TYPE))
14 #define IS_SUBBASE2_CLASS(k)              (G_TYPE_CHECK_CLASS_TYPE ((k), SUBBASE2_TYPE))
15 #define SUBBASE2_GET_CLASS(o)             (G_TYPE_INSTANCE_GET_CLASS ((o), SUBBASE2_TYPE, Subbase2Class))
16 #define SUBBASE2_CAST(obj)              ((Subbase2*)(obj))
17 
18 
19 typedef struct _Subbase2        Subbase2;
20 typedef struct _Subbase2Class   Subbase2Class;
21 typedef struct _Subbase2Private Subbase2Private;
22 
23 
24 struct _Subbase2
25 {
26     Base    parent;
27 };
28 
29 struct _Subbase2Class
30 {
31     BaseClass    parentclass;
32 };
33 
34 GType                 subbase2_get_type  (void);
35 Subbase2 *        subbase2_new(void);
36 void                    subbase2_dance_dance(Subbase2    *self,char *dance);
37 
38 G_END_DECLS
39 #endif /* ABSTRACTMODEL_H_ */
复制代码

  subbase2.c

复制代码
 1 #include "subbase2.h"
 2 #include <string.h>
 3 
 4 //子类的宏定义,继承父类类型
 5 G_DEFINE_TYPE(Subbase2, subbase2, BASE_TYPE);
 6 
 7 #define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SUBBASE2_TYPE, Subbase2))
 8 
 9 struct _Subbase2Private
10 {
11 };
12 
13 static void dispose_od(GObject *object);
14 static void finalize_od(GObject *object);
15 static void showSkill_od(Base *self);
16 static char *getSkill_od(Base *self);
17 
18 static void subbase2_class_init(Subbase2Class *klass)
19 {
20     GObjectClass *object_class = G_OBJECT_CLASS(klass);
21     g_type_class_add_private(klass, sizeof(Subbase2Private));
22     object_class->dispose = dispose_od;
23     object_class->finalize = finalize_od;
24     BaseClass *baseClass = BASE_CLASS(klass);
25     baseClass->getSkill=getSkill_od;
26     baseClass->showKill=showSkill_od;
27 }
28 
29 static void subbase2_init(Subbase2 *self)
30 {
31     Subbase2Private *priv = GET_PRIVATE(self);
32 }
33 
34 static void dispose_od(GObject *object)
35 {
36     Subbase2 *self = SUBBASE2(object);
37     Subbase2Private *priv = GET_PRIVATE(self);
38 
39     G_OBJECT_CLASS(subbase2_parent_class)->dispose(object);
40 }
41 
42 static void finalize_od(GObject *object)
43 {
44     Subbase2 *self = SUBBASE2(object);
45     Subbase2Private *priv = GET_PRIVATE(self);
46 
47     G_OBJECT_CLASS(subbase2_parent_class)->finalize(object);
48 }
49 static void showSkill_od(Base *self)
50 {
51     g_print("I ' m dancing\n");
52 }
53 static char *getSkill_od(Base *self)
54 {
55     return "dance";
56 }
57 
58 Subbase2 *        subbase2_new(void)
59 {
60     Subbase2 *res = g_object_new(SUBBASE2_TYPE,NULL);
61     return res;
62 }
63 void    subbase2_dance_dance(Subbase2    *self,char *dance)
64 {
65     g_print("I ' m dancing a %s dance!\n",dance);
66 }
复制代码

测试文件:main.c

复制代码
 1 #include
 2 #include
 3 #include
 4 #include"base.h"
 5 #include"subbase1.h"
 6 #include"subbase2.h"
 7 #include<string.h>
 8 
 9 int main(void)
10 {
11     g_print("hell world!\n");
12     Subbase1 *test1 = subbase1_new();
13     Subbase1 *test2 = subbase1_new();
14     Subbase2 *test3 = subbase2_new();
15 
16     base_set_name(BASE(test1),"test1");
17     base_set_name(BASE(test2),"test2");
18     base_set_name(BASE(test3),"test3");
19 
20     g_print("name:%s\n",base_get_name(BASE(test1)));
21     g_print("name:%s\n",base_get_name(BASE(test2)));
22     g_print("name:%s\n",base_get_name(BASE(test3)));
23 
24     g_print("skill:%s\n",base_get_skill(BASE(test1)));
25     base_show_skill(BASE(test1));
26     g_print("skill:%s\n", base_get_skill(BASE(test3)));
27     base_show_skill(BASE(test3));
28 
29     subbase1_sing_song(test1,"我怀恋的");
30     subbase2_dance_dance(test3,"芭蕾");
31 
32     BASE(test1)->str = g_string_new("one");
33     g_print("%s\n",BASE(test1)->str->str);
34 
35     return EXIT_SUCCESS;
36 }
复制代码

3、总结

  如2的代码所示,其中涉及到了抽象、继承、重载等概念,C语言要使用面向对象来设计和解决问题,那么关于面向对象一般的基本特征也要了解和实现,要充分将这些实现方式转化为经验,这样再以后的面向对象设计中才能

驾轻就熟,也会更有效率。

  同时如大家所见,C语言要实现面向对象这一特征是较为复杂的,代码相对JAVA或python等也非常的多,但是在嵌入式或一些需要使用C语言来设计和解决问题的领域,使用面向对象设计是有着很大的好处的,其中最明显的就是

可以减轻设计的复杂度。

4、题外话

  在嵌入式领域C++的比重越来越来越大,著名的QT、openCV(一部分)等都是由C语言开发,C++开发嵌入式应用的效率上是有优势的,但是大部分的底层库还是得由C语言来实现,尤其是一些核心的东西需要C语言来支持

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多