亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

Chinaunix

標(biāo)題: 請教gtk c語言編程 [打印本頁]

作者: angelanpan    時(shí)間: 2005-12-07 09:07
標(biāo)題: 請教gtk c語言編程
在gtk中:
對象的定義
在GObject系統(tǒng)中,對象由三個(gè)部分組成:

1. 對象的ID標(biāo)識(唯一,無符號長整型,所有此類對象共同的標(biāo)識);
2. 對象的類結(jié)構(gòu)(唯一,結(jié)構(gòu)型,由對象的所有實(shí)例共同擁有);
3. 對象的實(shí)例(多個(gè),結(jié)構(gòu)型,對象的具體實(shí)現(xiàn))。

為什么要規(guī)定由這三個(gè)部分組成呢? 為什么不能直接像c++里面定義對象那樣定義呢?
這里為什么要區(qū)分類結(jié)構(gòu)和實(shí)例阿? 如果我在類結(jié)構(gòu)中也公用數(shù)據(jù),實(shí)例中也有公用數(shù)據(jù),那這兩個(gè)公用數(shù)據(jù)會有什么區(qū)別呢?
作者: renstone921    時(shí)間: 2005-12-07 14:50
這些問題你是從哪里看到的.我覺得你的理解有偏差.

為什么不能直接像c++里面定義對象那樣定義呢?

它開發(fā)時(shí),用的是c語言,c語言里又沒有class這個(gè)東西,而只有struct.

為什么要規(guī)定由這三個(gè)部分組成呢?

一個(gè)類

  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. };
復(fù)制代碼


一個(gè)對象
Cat cat;
class Cat描述了對創(chuàng)建的一個(gè)實(shí)例的在內(nèi)存中的布局信息(不考慮虛函數(shù)和靜態(tài)成員)

class Cat
被解釋為

  1. struct Cat
  2. {
  3.     int age_;
  4.     char sex_;
  5.     int noOfLegs;      
  6. };                                   //就象在c語言里一樣,只有定義了結(jié)構(gòu)類型,并定義了一個(gè)結(jié)構(gòu)類型的變量后,變量將會在程序執(zhí)行到變量定義部分時(shí)產(chǎn)生.

  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. }
復(fù)制代碼


先說一下對象是如何產(chǎn)生的.
就象定義普通變量一樣,編譯器產(chǎn)生調(diào)整堆棧的棧頂指針的代碼,當(dāng)分配單位為sizeof(struct Cat)并且空間分配完畢,然后在根據(jù)調(diào)用的構(gòu)造函數(shù)的形式,來決定使用的是Cat(struct Cat* aCat)或是Cat(struct Cat* aCat, int age, char sex, int noOfLegs);


  1. Cat aCat(3, 'm', 4);
  2. aCat.Roll();
復(fù)制代碼

被編譯器轉(zhuǎn)換成了

  1. struct Cat aCat;
  2. Cat(&aCat, 3, 'm', 4);
  3. Roll(&aCat);
復(fù)制代碼

的調(diào)用序列.

所以,你在源代碼里面定義了一個(gè)結(jié)構(gòu)類型, 就是告訴編譯器假如我定義了一個(gè)這個(gè)結(jié)構(gòu)類型的變量,你編譯器應(yīng)當(dāng)如何對從這個(gè)變量的地址開始的空間內(nèi)的某幾個(gè)字節(jié)做如何的解釋,把這幾個(gè)字節(jié)當(dāng)作是一個(gè)整型的還是一個(gè)浮點(diǎn)型的數(shù)據(jù).

考慮一下它體現(xiàn)了什么信息,當(dāng)編譯完成時(shí),每個(gè)函數(shù)都被放入了可執(zhí)行模塊了,每個(gè)函數(shù)都有一個(gè)確定入口地址,以及函數(shù)參數(shù)傳遞的方式,還有一個(gè)決定了你對某些內(nèi)存空間如何進(jìn)行解釋的結(jié)構(gòu)類型,這些信息都在程序執(zhí)行前就確定了.

這些信息,可以視為是類的元信息.-------對結(jié)構(gòu)的解釋,以及函數(shù)的描述信息

類是一個(gè)編譯期的概念,而實(shí)例是一個(gè)執(zhí)行期的概念,就像只有正在運(yùn)行的可執(zhí)行程序才能稱之為進(jìn)程一樣.

class Cat 定義了多少個(gè)實(shí)例,內(nèi)存中就存在多少份
struct Cat
{
    int age_;
    char sex_;
    int noOfLegs;      
};               
而它們是共用上面定義的那些方法的.

如果我在類結(jié)構(gòu)中也公用數(shù)據(jù),實(shí)例中也有公用數(shù)據(jù),那這兩個(gè)公用數(shù)據(jù)會有什么區(qū)別呢?

類中定義公用數(shù)據(jù),只是告訴編譯器檢查可存取性.

實(shí)例中有公用數(shù)據(jù)-----------這句話很別扭,因?yàn)槊總(gè)實(shí)例都有一份自己的數(shù)據(jù).

思維有點(diǎn)混亂,不知道說的是否清楚.

1. 對象的ID標(biāo)識(唯一,無符號長整型,所有此類對象共同的標(biāo)識);
在一個(gè)庫中,要表示出一個(gè)類之間的的關(guān)系,假定是繼承關(guān)系,當(dāng)你的語言里面并沒有表示結(jié)構(gòu)之間的關(guān)系的特性時(shí),最簡單的方法,就是給父類分配一個(gè)固定的唯一的ID,并在子類中有自身的ID和父類的ID,這樣來表示類之間的層次關(guān)系.
舉個(gè)例子
描述一種結(jié)構(gòu)之間的繼承關(guān)系
[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;            //自身的.

這樣可以簡單的表示一種類之間層次結(jié)構(gòu)的方法.在一般的框架里面,實(shí)現(xiàn)的方法一般都是單根樹.

2. 對象的類結(jié)構(gòu)(唯一,結(jié)構(gòu)型,由對象的所有實(shí)例共同擁有);

就是前面所提到的類的元信息,對一個(gè)類實(shí)例所代表的內(nèi)存空間如何解釋以及如何調(diào)用類方法,這些信息是類的所有實(shí)例所共享的,編譯期內(nèi)就確定了

3.對象的實(shí)例.
每個(gè)對象都具有自身的數(shù)據(jù)成員,每實(shí)例化一份對象,就會產(chǎn)生類的所有數(shù)據(jù)成員的一份拷貝.只有到執(zhí)行期才可確定.

gtk就是一個(gè)用c語言寫的框架庫.
作者: angelanpan    時(shí)間: 2005-12-07 16:10
那些題目是因?yàn)槲易罱鼊傞_始接觸gobject系統(tǒng),理解還不是很深刻,隨意的寫的。

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

可能是我開始的理解有誤差,現(xiàn)在我想問一下:

  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. ......
復(fù)制代碼

上面的代碼是從項(xiàng)目中的一個(gè)頭文件copy來的。
為什么這里要定義兩個(gè)結(jié)構(gòu)?
SimServerClass這個(gè)結(jié)構(gòu)主要用來做什么?
作者: angelanpan    時(shí)間: 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.

我的那段代碼里面也確實(shí)有兩個(gè)結(jié)構(gòu):
struct _SimServer
struct _SimServerClass

是不是在gobject里面為了實(shí)現(xiàn) OO ,定義兩個(gè)結(jié)構(gòu)來對應(yīng)一個(gè)對象?


我想問一下:這兩個(gè)結(jié)構(gòu)是什么關(guān)系?  SimServerClass這個(gè)結(jié)構(gòu)又到底是干什么用的 ?
作者: renstone921    時(shí)間: 2005-12-07 18:50
我在前面已經(jīng)提到過

不考慮虛函數(shù)的情況下,編譯器實(shí)際上是將一個(gè)類看做是一些數(shù)據(jù)和一些數(shù)據(jù)處理函數(shù)的組合.
一些信息是類的每個(gè)實(shí)例都有的 -------- 數(shù)據(jù)成員
另一些信息是被所有類的實(shí)例所共享的. --------- 成員函數(shù)

編譯器處理產(chǎn)生

  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. }
復(fù)制代碼


這實(shí)際上可以概括成兩個(gè)


  1. 每個(gè)實(shí)例具有的,
  2. struct Cat
  3. {
  4.     int age_;
  5.     char sex_;
  6.     int noOfLegs;
  7. };

  8. 所有實(shí)例所共享的,是對類的元信息的描述
  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); */這個(gè)應(yīng)當(dāng)不是合法的,但只要定義一個(gè)合法的名字就可以了
  15.      
  16.      void (*Mum)(struct Cat* aCat);
  17.      void (* Roll)(struct Cat* aCat)
  18. };

  19. 如果有靜態(tài)成員的話,也應(yīng)當(dāng)被添加到CatClass里面去
  20. 上面的結(jié)構(gòu)里面,定義了一些函數(shù)指針,這些函數(shù)指針?biāo)赶虻暮瘮?shù)完成相應(yīng)成員函數(shù)的功能.


復(fù)制代碼

所以,
struct _SimServer
struct _SimServerClass
這兩個(gè)結(jié)構(gòu)之間的關(guān)系就是被分離出來數(shù)據(jù)成員和被包裝起來的數(shù)據(jù)處理函數(shù)之間的關(guān)系,一個(gè)數(shù)據(jù)處理函數(shù)可以處理同類型的多個(gè)數(shù)據(jù).
作者: angelanpan    時(shí)間: 2005-12-08 09:18
非常謝謝你的詳細(xì)解答,我已經(jīng)理解你的意思了。
但是我還要問個(gè)小問題:
  假如我在struct _SimServer也定義幾個(gè)函數(shù)指針,來作為成員函數(shù)呢 ?也就是所有實(shí)例的中的那些作為函數(shù)成員的指針都指向一個(gè)函數(shù)(只要正確寫出*_instance_init()函數(shù)就可以實(shí)現(xiàn)吧),這樣也應(yīng)該可以吧 ?會帶來些什么問題呢 ?




歡迎光臨 Chinaunix (http://www.72891.cn/) Powered by Discuz! X3.2