• glib实践篇:父类与子类


    前言:

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

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

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

    1、设计说明

      开发语言:C语言

      基础库:glib

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

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

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

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

      base.h

     1 #ifndef __BASE_H__
     2 #define __BASE_H__
     3 
     4 #include <glib.h>
     5 #include <stdio.h>
     6 #include <glib-object.h>
     7 G_BEGIN_DECLS
     8 
     9 #define BASE_TYPE                    (base_get_type ())//该对象的类型
    10 #define BASE(o)                       (G_TYPE_CHECK_INSTANCE_CAST ((o), BASE_TYPE, Base))//类型转换,转换为该对象的类型
    11 #define BASE_CLASS(k)                 (G_TYPE_CHECK_CLASS_CAST((k), BASE_TYPE, BaseClass))
    12 #define IS_BASE(o)                    (G_TYPE_CHECK_INSTANCE_TYPE ((o), BASE_TYPE))
    13 #define IS_BASE_CLASS(k)              (G_TYPE_CHECK_CLASS_TYPE ((k), BASE_TYPE))
    14 #define BASE_GET_CLASS(o)             (G_TYPE_INSTANCE_GET_CLASS ((o), BASE_TYPE, BaseClass))
    15 #define BASE_CAST(obj)              ((Base*)(obj))
    16 
    17 
    18 typedef struct _Base        Base;
    19 typedef struct _BaseClass   BaseClass;
    20 typedef struct _BasePrivate BasePrivate;
    21 
    22 
    23 struct _Base
    24 {
    25     GObject    parent;
    26     //设置共有变量,提供给子类访问
    27     GString *str;
    28 };
    29 
    30 struct _BaseClass
    31 {
    32     GObjectClass    parentclass;
    33     //设置设置写和读名字的方法,由子类重载
    34     void (*showKill)(Base *self);
    35     char *(*getSkill)(Base *self);
    36 };
    37 
    38 GType                 base_get_type  (void);
    39 //这些方法被子类所共有,其中skill的操作方法需要由子类重载。
    40 void               base_set_name(Base *self,char *name);
    41 char *            base_get_name(Base *self);
    42 void                 base_show_skill(Base *self);
    43 char *            base_get_skill(Base *self);
    44 
    45 G_END_DECLS
    46 
    47 
    48 
    49 #endif /* ABSTRACTMODEL_H_ */

    basec.c

     1 #include "base.h"
     2 #include <string.h>
     3 
     4 //父类即抽象类的宏定义,继承自object
     5 G_DEFINE_ABSTRACT_TYPE(Base, base, G_TYPE_OBJECT);
     6 
     7 #define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), BASE_TYPE, Base))
     8 
     9 struct _BasePrivate
    10 {
    11     char *name;
    12 };
    13 
    14 static void dispose_od(GObject *object);
    15 static void finalize_od(GObject *object);
    16 
    17 static void base_class_init(BaseClass *klass)
    18 {
    19     GObjectClass *object_class = G_OBJECT_CLASS(klass);
    20     g_type_class_add_private(klass, sizeof(BasePrivate));
    21     object_class->dispose = dispose_od;
    22     object_class->finalize = finalize_od;
    23 }
    24 
    25 static void base_init(Base *self)
    26 {
    27     BasePrivate *priv = GET_PRIVATE(self);
    28     self->str = g_string_new("暴露出来给你们访问的");
    29 }
    30 static void dispose_od(GObject *object)
    31 {
    32     Base *self = BASE(object);
    33     BasePrivate *priv = GET_PRIVATE(self);
    34     if(self->str)
    35     {
    36         g_string_free(self->str,TRUE);
    37         self->str=NULL;
    38     }
    39     G_OBJECT_CLASS(base_parent_class)->dispose(object);
    40 }
    41 
    42 static void finalize_od(GObject *object)
    43 {
    44     Base *self = BASE(object);
    45     BasePrivate *priv = GET_PRIVATE(self);
    46 
    47     G_OBJECT_CLASS(base_parent_class)->finalize(object);
    48 }
    49 
    50 void    base_set_name(Base *self,char *name)
    51 {
    52     BasePrivate *priv = GET_PRIVATE(self);
    53     priv->name = strdup(name);
    54 }
    55 char *base_get_name(Base *self)
    56 {
    57     BasePrivate *priv = GET_PRIVATE(self);
    58     return priv->name;
    59 }
    60 
    61 void base_show_skill(Base *self)
    62 {
    63     if (self)
    64     {
    65         BaseClass *baseClass = BASE_GET_CLASS(self);
    66         baseClass->showKill(self);
    67     }
    68 }
    69 char * base_get_skill(Base *self)
    70 {
    71     char *skill = NULL;
    72     if (self)
    73     {
    74         BaseClass *baseClass = BASE_GET_CLASS(self);
    75         skill = baseClass->getSkill(self);
    76     }
    77     return skill;
    78 }

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

      subbase1.h

     1 #ifndef __SUBBASE1_H__
     2 #define __SUBBASE1_H__
     3 
     4 #include <glib.h>
     5 #include <stdio.h>
     6 #include <glib-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!
    ");
    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!
    ",song);
    66 }

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

      subbase2.h

     1 #ifndef __SUBBASE2_H__
     2 #define __SUBBASE2_H__
     3 
     4 #include <glib.h>
     5 #include <stdio.h>
     6 #include <glib-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
    ");
    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!
    ",dance);
    66 }

    测试文件:main.c

     1 #include<glib.h>
     2 #include<stdio.h>
     3 #include<stdlib.h>
     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!
    ");
    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
    ",base_get_name(BASE(test1)));
    21     g_print("name:%s
    ",base_get_name(BASE(test2)));
    22     g_print("name:%s
    ",base_get_name(BASE(test3)));
    23 
    24     g_print("skill:%s
    ",base_get_skill(BASE(test1)));
    25     base_show_skill(BASE(test1));
    26     g_print("skill:%s
    ", 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
    ",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语言来支持

  • 相关阅读:
    JAVA第六次作业
    20194672自动生成四则运算题第一版报告
    20194672自动生成四则运算第一版报告
    第四次博客作业--结对项目
    第9次作业--接口及接口回调
    第8次作业--继承
    软件工程第三次作业——关于软件质量保障初探
    第7次作业——访问权限、对象使用
    第6次作业--static关键字、对象
    Java输出矩形的面积和周长
  • 原文地址:https://www.cnblogs.com/xishuichangliu/p/6209199.html
Copyright © 2020-2023  润新知