免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3599 | 回复: 5
打印 上一主题 下一主题

请教gtk c语言编程 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-12-07 09:07 |只看该作者 |倒序浏览
在gtk中:
对象的定义
在GObject系统中,对象由三个部分组成:

1. 对象的ID标识(唯一,无符号长整型,所有此类对象共同的标识);
2. 对象的类结构(唯一,结构型,由对象的所有实例共同拥有);
3. 对象的实例(多个,结构型,对象的具体实现)。

为什么要规定由这三个部分组成呢? 为什么不能直接像c++里面定义对象那样定义呢?
这里为什么要区分类结构和实例阿? 如果我在类结构中也公用数据,实例中也有公用数据,那这两个公用数据会有什么区别呢?

论坛徽章:
0
2 [报告]
发表于 2005-12-07 14:50 |只看该作者
这些问题你是从哪里看到的.我觉得你的理解有偏差.

为什么不能直接像c++里面定义对象那样定义呢?

它开发时,用的是c语言,c语言里又没有class这个东西,而只有struct.

为什么要规定由这三个部分组成呢?

一个类

  1. class Cat
  2. {
  3. public:
  4.      Cat();
  5.      Cat(int age, char sex, int noOfLegs);
  6.      ~Cat();
  7.      
  8.      void Mum();
  9.      void Roll();
  10. private:
  11.     int age_;
  12.     char sex_;
  13.     int noOfLegs;     
  14. };
复制代码


一个对象
Cat cat;
class Cat描述了对创建的一个实例的在内存中的布局信息(不考虑虚函数和静态成员)

class Cat
被解释为

  1. struct Cat
  2. {
  3.     int age_;
  4.     char sex_;
  5.     int noOfLegs;      
  6. };                                   //就象在c语言里一样,只有定义了结构类型,并定义了一个结构类型的变量后,变量将会在程序执行到变量定义部分时产生.

  7. Cat(struct Cat* aCat)              
  8. {
  9. }
  10. Cat(struct Cat* aCat, int age, char sex, int noOfLegs)
  11. {
  12. }
  13. ~Cat(struct Cat* aCat)
  14. {
  15. }
  16.      
  17. void Mum(struct Cat* aCat)
  18. {
  19. }
  20. void Roll(struct Cat* aCat)
  21. {
  22. }
复制代码


先说一下对象是如何产生的.
就象定义普通变量一样,编译器产生调整堆栈的栈顶指针的代码,当分配单位为sizeof(struct Cat)并且空间分配完毕,然后在根据调用的构造函数的形式,来决定使用的是Cat(struct Cat* aCat)或是Cat(struct Cat* aCat, int age, char sex, int noOfLegs);


  1. Cat aCat(3, 'm', 4);
  2. aCat.Roll();
复制代码

被编译器转换成了

  1. struct Cat aCat;
  2. Cat(&aCat, 3, 'm', 4);
  3. Roll(&aCat);
复制代码

的调用序列.

所以,你在源代码里面定义了一个结构类型, 就是告诉编译器假如我定义了一个这个结构类型的变量,你编译器应当如何对从这个变量的地址开始的空间内的某几个字节做如何的解释,把这几个字节当作是一个整型的还是一个浮点型的数据.

考虑一下它体现了什么信息,当编译完成时,每个函数都被放入了可执行模块了,每个函数都有一个确定入口地址,以及函数参数传递的方式,还有一个决定了你对某些内存空间如何进行解释的结构类型,这些信息都在程序执行前就确定了.

这些信息,可以视为是类的元信息.-------对结构的解释,以及函数的描述信息

类是一个编译期的概念,而实例是一个执行期的概念,就像只有正在运行的可执行程序才能称之为进程一样.

class Cat 定义了多少个实例,内存中就存在多少份
struct Cat
{
    int age_;
    char sex_;
    int noOfLegs;      
};               
而它们是共用上面定义的那些方法的.

如果我在类结构中也公用数据,实例中也有公用数据,那这两个公用数据会有什么区别呢?

类中定义公用数据,只是告诉编译器检查可存取性.

实例中有公用数据-----------这句话很别扭,因为每个实例都有一份自己的数据.

思维有点混乱,不知道说的是否清楚.

1. 对象的ID标识(唯一,无符号长整型,所有此类对象共同的标识);
在一个库中,要表示出一个类之间的的关系,假定是继承关系,当你的语言里面并没有表示结构之间的关系的特性时,最简单的方法,就是给父类分配一个固定的唯一的ID,并在子类中有自身的ID和父类的ID,这样来表示类之间的层次关系.
举个例子
描述一种结构之间的继承关系
[code]
struct Object
{
};
int ObjectParentID = -1;         //无父类
int ObjectID = 0;                    //自身的类ID
struct Person
{

};
int PersonParentID = 0;         //父类为Object
int PersonID = 1;                  //自身的
struct Employee;
{c
};
int EmployeeParentID = 1;   //父类位Person
int EmployeeID = 2;            //自身的.

这样可以简单的表示一种类之间层次结构的方法.在一般的框架里面,实现的方法一般都是单根树.

2. 对象的类结构(唯一,结构型,由对象的所有实例共同拥有);

就是前面所提到的类的元信息,对一个类实例所代表的内存空间如何解释以及如何调用类方法,这些信息是类的所有实例所共享的,编译期内就确定了

3.对象的实例.
每个对象都具有自身的数据成员,每实例化一份对象,就会产生类的所有数据成员的一份拷贝.只有到执行期才可确定.

gtk就是一个用c语言写的框架库.

论坛徽章:
0
3 [报告]
发表于 2005-12-07 16:10 |只看该作者
那些题目是因为我最近刚开始接触gobject系统,理解还不是很深刻,随意的写的。

非常感谢,我理解你的意思了。

可能是我开始的理解有误差,现在我想问一下:

  1. ......
  2. typedef struct _SimServer        SimServer;
  3. typedef struct _SimServerClass   SimServerClass;
  4. typedef struct _SimServerPrivate SimServerPrivate;

  5. struct _SimServer {
  6.   GObject parent;

  7.   SimServerPrivate *_priv;
  8. };

  9. struct _SimServerClass {
  10.   GObjectClass parent_class;
  11. };
  12. ......
复制代码

上面的代码是从项目中的一个头文件copy来的。
为什么这里要定义两个结构?
SimServerClass这个结构主要用来做什么?

论坛徽章:
0
4 [报告]
发表于 2005-12-07 17:26 |只看该作者
在Gobject Reference Manual 里面提到:
Every object must define two structures: its class structure and its instance structure. All class structures must contain as first member a GTypeClass structure. All instance structures must contain as first member a GTypeInstance structure.

我的那段代码里面也确实有两个结构:
struct _SimServer
struct _SimServerClass

是不是在gobject里面为了实现 OO ,定义两个结构来对应一个对象?


我想问一下:这两个结构是什么关系?  SimServerClass这个结构又到底是干什么用的 ?

论坛徽章:
0
5 [报告]
发表于 2005-12-07 18:50 |只看该作者
我在前面已经提到过

不考虑虚函数的情况下,编译器实际上是将一个类看做是一些数据和一些数据处理函数的组合.
一些信息是类的每个实例都有的 -------- 数据成员
另一些信息是被所有类的实例所共享的. --------- 成员函数

编译器处理产生

  1. struct Cat
  2. {
  3.     int age_;
  4.     char sex_;
  5.     int noOfLegs;
  6. };

  7. Cat(struct Cat* aCat)              
  8. {
  9. }
  10. Cat(struct Cat* aCat, int age, char sex, int noOfLegs)
  11. {
  12. }
  13. ~Cat(struct Cat* aCat)
  14. {
  15. }
  16.      
  17. void Mum(struct Cat* aCat)
  18. {
  19. }
  20. void Roll(struct Cat* aCat)
  21. {
  22. }
复制代码


这实际上可以概括成两个


  1. 每个实例具有的,
  2. struct Cat
  3. {
  4.     int age_;
  5.     char sex_;
  6.     int noOfLegs;
  7. };

  8. 所有实例所共享的,是对类的元信息的描述
  9. struct CatClass
  10. {
  11.       void  (*Cat)(struct Cat* aCat);              
  12.    
  13.       void (*Cat)(struct Cat* aCat, int age, char sex, int noOfLegs);
  14. /*      void (*~Cat)(struct Cat* aCat); */这个应当不是合法的,但只要定义一个合法的名字就可以了
  15.      
  16.      void (*Mum)(struct Cat* aCat);
  17.      void (* Roll)(struct Cat* aCat)
  18. };

  19. 如果有静态成员的话,也应当被添加到CatClass里面去
  20. 上面的结构里面,定义了一些函数指针,这些函数指针所指向的函数完成相应成员函数的功能.


复制代码

所以,
struct _SimServer
struct _SimServerClass
这两个结构之间的关系就是被分离出来数据成员和被包装起来的数据处理函数之间的关系,一个数据处理函数可以处理同类型的多个数据.

论坛徽章:
0
6 [报告]
发表于 2005-12-08 09:18 |只看该作者
非常谢谢你的详细解答,我已经理解你的意思了。
但是我还要问个小问题:
  假如我在struct _SimServer也定义几个函数指针,来作为成员函数呢 ?也就是所有实例的中的那些作为函数成员的指针都指向一个函数(只要正确写出*_instance_init()函数就可以实现吧),这样也应该可以吧 ?会带来些什么问题呢 ?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP