C和C++的面向对象专题(2)——C语言也能实现面向对象

本专栏文章列表

一、何为面向对象

二、C语言也能实现面向对象

三、C++中的不优雅特性

四、解决封装,避免接口

五、合理使用模板,避免代码冗余

六、C++也能反射

七、单例模式解决静态成员对象和全局对象的构造顺序难题

八、更为高级的预处理器PHP

二、C语言也能实现面向对象

今天要为大家介绍C语言的面向对象设计方法,正如题记上面所说,面向对象是一种思想,而并非是一种语言,我们将会介绍C语言实现的面向对象开发方式。

简单实用的C语言面向对象设计思路

众所周知,C++中的面向对象十分方便,但在C中,并没有类,但我们可以通过C的结构体来实现,然后,手动将this指针传入

目前这个方法,应该是C语言设计中,简便易用的方式,而且能较好的体现面向对象的设计思路,然而遗憾的是,没有继承和多态。

例如,我们这样一个C++类

class test {
public:
    test(char* str, int k) {
        this->str = str;
        this->k = k;
    }
    void ShowMessage() {
        for (int i = 0; i < k; ++i)
            printf("%s\n", str);
    }
private:
    int k;
    char* str;
};

那么我们可以这样转换为一个C类

/* test.h */

typedef struct _test {
    int k;
    char* str;
} test;

test* TestCreate();
void ShowMessage(test*);
/* test.c */

test* TestCreate() {
    return (test*) malloc(sizeof(test));
}

void ShowMessage(test* t) {
    int i;
    for (i = 0; i < t->k; ++i) {
        printf("%s\n", t->str);
    }
}

其实思路也很清晰,思路简单易懂,实现也很清新明快,在各类C工程中使用极为广泛。

复杂的基于GObject的面向对象程序设计

如果你希望学习C语言的GUI程序设计,那么,必定要学习的就是GObject的类实现方式。

GObject相当于从C层面上模拟了一个C++的类对象模型,实现当然相对复杂的多。

下面我们来实际看一下一个GTK的窗口类,这是GTK+-3.0的一段样例:

/* appwin.h */
#ifndef APPWIN_H
#define APPWIN_H

#include "app.h"
#include <gtk/gtk.h>

/* 该类的类型定义以及类型转换宏 */
#define APP_WINDOW_TYPE (app_window_get_type())
#define APP_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), APP_WINDOW_TYPE, AppWindow))

/* 该类分成两部分,一部分是成员,一部分是类本身 */
typedef struct _AppWindow      AppWindow;
typedef struct _AppWindowClass AppWindowClass;

GType      app_window_get_type (void);
AppWindow* app_window_new      (App *app);
void       app_window_open     (AppWindow *win, GFile *file);

#endif // APPWIN_H

而其真实的定义是在.c文件中


struct _AppWindow
{
    GtkApplicationWindow parent;
};

struct _AppWindowClass
{
    GtkApplicationWindowClass parent_class;
};

typedef struct _AppWindowPrivate AppWindowPrivate;

struct _AppWindowPrivate
{
    GSettings *settings;
    GtkWidget *stack;
    GtkWidget *search;
    GtkWidget *searchbar;
    GtkWidget *searchentry;
    GtkWidget *gears;
    GtkWidget *sidebar;
    GtkWidget *words;
    GtkWidget *lines;
    GtkWidget *lines_label;
};

G_DEFINE_TYPE_WITH_PRIVATE(AppWindow, app_window, GTK_TYPE_APPLICATION_WINDOW);

/* 后面有具体的实现方法,这里就不一一列举 */

我们发现,这种定义方式比C++中的其实更有优势,封装的更加彻底。为何这样说呢?首先,我们的声明文件十分的简洁,如果公开方法不修改的话,那么将其余内容如何改动,都不会影响我们的外部接口。

其次,由于需要显示的向GObject注册,那么动态进行类注册就成为可能,这样的设计优势表现在哪里呢?多语言的互通性就很好了,因为很多动态语言,是支持类的动态加载以及反射加载的。

另外,vala语言就是基于GObject类型的,他是一门新兴的编译时语言,但其也有很多动态语言的特性,用其开发gtk程序,比C具有明显的优势。

时间: 2024-10-22 05:16:33

C和C++的面向对象专题(2)——C语言也能实现面向对象的相关文章

C和C++的面向对象专题(8)——更为高级的预处理器PHP

本专栏文章列表 一.何为面向对象 二.C语言也能实现面向对象 三.C++中的不优雅特性 四.解决封装,避免接口 五.合理使用模板,避免代码冗余 六.C++也能反射 七.单例模式解决静态成员对象和全局对象的构造顺序难题 八.更为高级的预处理器PHP 八.更为高级的预处理器PHP C++的宏在某些情况下非常难用,例如将代码展开成为这样: Macro( A, B, C, D ) => func("A", A); func("B", B); func("C&

C和C++的面向对象专题(1)——何为面向对象

题记: 面向对象是一种思想,而不是一门语言 我们上哪去找对象,都面向对象去了 本专栏文章列表 一.何为面向对象 二.C语言也能实现面向对象 三.C++中的不优雅特性 四.解决封装,避免接口 五.合理使用模板,避免代码冗余 六.C++也能反射 七.单例模式解决静态成员对象和全局对象的构造顺序难题 八.更为高级的预处理器PHP 一.何为面向对象 现在学软件开发,都讲面向对象的编程模型,其实也很简单.用一句话来总结,面向对象就是将方法和方法的属性整合在一起,让每个方法引用的属性值尽可能在对象内部,对外

C和C++的面向对象专题(3)——C++中的不优雅特性

本专栏文章列表 一.何为面向对象 二.C语言也能实现面向对象 三.C++中的不优雅特性 四.解决封装,避免接口 五.合理使用模板,避免代码冗余 六.C++也能反射 七.单例模式解决静态成员对象和全局对象的构造顺序难题 八.更为高级的预处理器PHP 三.C++中的不优雅特性 今天来说一说C++中不优雅的一些问题,C++虽然是面向对象的设计语言,但也有很多缺陷和弊病,我们将会讨论如何通过良好的设计解决这些问题. C++编译缓慢 C++编译慢已经成为了业界共识,一个大型C++项目甚至要用专用的服务器编

C和C++的面向对象专题(9)——Gtkmm的最佳实践

本专栏文章列表 一.何为面向对象 二.C语言也能实现面向对象 三.C++中的不优雅特性 四.解决封装,避免接口 五.合理使用模板,避免代码冗余 六.C++也能反射 七.单例模式解决静态成员对象和全局对象的构造顺序难题 八.更为高级的预处理器PHP 九.Gtkmm的最佳实践 九.Gtkmm的最佳实践 在跨平台的gui开发中,Qt一直是非常受欢迎的GUI开发框架,但Qt一个是依赖反射,需要特殊的预处理步骤,一个是库太过庞大,这就造成了一些不便的地方.今天介绍给大家的是Gtk库的C++绑定,Gtkmm

C和C++的面向对象专题(7)——单例模式解决静态成员对象和全局对象的构造顺序难题

本专栏文章列表 一.何为面向对象 二.C语言也能实现面向对象 三.C++中的不优雅特性 四.解决封装,避免接口 五.合理使用模板,避免代码冗余 六.C++也能反射 七.单例模式解决静态成员对象和全局对象的构造顺序难题 八.更为高级的预处理器PHP 七.单例模式解决静态成员对象和全局对象的构造顺序难题 上回书说道,我们的程序有一个隐藏的漏洞,如果ClassRegister这个类所在的.o文件,如果在所有.o文件中是第一个被链接的的,那么就不会出问题. 这么说太抽象了,让我们画个图表 ClassRe

C和C++的面向对象专题(6)——C++也能反射

本专栏文章列表 一.何为面向对象 二.C语言也能实现面向对象 三.C++中的不优雅特性 四.解决封装,避免接口 五.合理使用模板,避免代码冗余 六.C++也能反射 七.单例模式解决静态成员对象和全局对象的构造顺序难题 八.更为高级的预处理器PHP 六.C++也能反射 今天我们来探讨C++的反射问题,缺乏反射机制一直是C++的大问题,很多系统的设计时,需要根据外部资源文件的定义,动态的调用内部的函数和接口,如果没有反射,将很难将外部的数据,转换为内部的方法. Java和.net的反射机制很容易实现

C和C++的面向对象专题(5)——合理使用模板,避免代码冗余

本专栏文章列表 一.何为面向对象 二.C语言也能实现面向对象 三.C++中的不优雅特性 四.解决封装,避免接口 五.合理使用模板,避免代码冗余 六.C++也能反射 七.单例模式解决静态成员对象和全局对象的构造顺序难题 八.更为高级的预处理器PHP 五.合理使用模板,避免代码冗余 下面我们来讨论一下,如何解决模板的不易封装的问题. 我们提供这样一种思路,对于链表一类的通用类型,我们尽量采取强制类型转换的方式,尽量避免模板的滥用. 同样,我们应该避免对结构体的直接存储,尽量使用类似java的指针传递

C和C++的面向对象专题(4)——解决封装,避免接口

本专栏文章列表 一.何为面向对象 二.C语言也能实现面向对象 三.C++中的不优雅特性 四.解决封装,避免接口 五.合理使用模板,避免代码冗余 六.C++也能反射 七.单例模式解决静态成员对象和全局对象的构造顺序难题 八.更为高级的预处理器PHP 四.解决封装,避免接口 恩,今天我们来讨论,如何通过设计,解决C++中的不优雅特性,改进项目的结构,改善编译速度. 上次我们提到,如果一个类的封装不好,容易导致种种不便,那么如何设计能够避免这种现象呢? class test { public: voi

Cocos2d-x 脚本语言Lua中的面向对象

Cocos2d-x 脚本语言Lua中的面向对象 面向对象不是针对某一门语言,而是一种思想.在面向过程的语言也能够使用面向对象的思想来进行编程. 在Lua中,并没有面向对象的概念存在,没有类的定义和子类的定义.但相同在Lua中能够利用面向对象的思想来实现面向对象的类继承. 一.复制表的方式面向对象 --Lua中的面向对象 --[[ 复制表方式面向对象 參数为一张表.通过遍历这张表取值,赋给一张空表,最后返回新建的表.来达到克隆表 ]] function clone(tab) local ins =