用C 實現屬性

2021-06-02 14:58:10 字數 3724 閱讀 8611

tmyclass =

class

private

fvalue: integer;

funcationgetvalue: integer;

proceduresetvalue(value: integer);

public

property value: integer read getvalue write setvalue;

end;

紅色部分就是屬性的宣告,以後可以直接對value進行讀寫,像下面這樣:

myclass.value

:=100;

v = myclass.value;

屬性有幾個顯而易見的好處:

c++原生沒有支援屬性,但這個語言的特點就是語法強大,通過一些高階屬性就可以實現其他語言的特性。要實現屬性,c++當然是可以勝任了,而且實現方式有很多,我在網上就看過幾種實現。不過在這裡我要講另外兩種實現,一種是我想到的,另一種是編譯器的擴充套件。

先看第一種,網上通常的實現是用「模板+操作符過載」的方式,這種方式需要在類的建構函式中初始化模板類成員,並且模板類包含了3個成員:外部類指標和讀寫函式指標。這個模板類成員就是「屬性」,乙個屬性將浪費掉一些儲存,如果乙個類存在大量屬性,則這個類的空間尺寸是可觀的。

我的實現是用「本地類+操作符過載」的方式,用了3種本地類,分別實現「唯讀,只寫,可讀寫」三種屬性,用巨集包裝起來方便使用,請看下面的**:

// 取外部類例項指標(this)

// outclass 外部類名

// localclassmem 本地類成員

#define

outclass_this(outclass, localclassmem) ((outclass*)((unsigned char*)this - offsetof(outclass, localclassmem)))

// 屬性定義巨集

// cls 定義屬性的類

// type 屬性的型別

// propname 屬性名

// getter 讀函式

// setter 寫函式

#define

property_r(cls, type, propname, getter) /

class property_##getter /

/} propname

#define

property_w(cls, type, propname, setter) /

class property_##setter /

/} propname 

#define

property_rw(cls, type, propname, getter, setter) /

class property_##getter_##setter /

/property_##getter_##setter &operator = (const type& value) /

/} propname

有了這幾個巨集,就可以寫乙個測試類來看看結果了:

classtest

intgetvaluer()

voidsetvaluew(

const

floatvalue)

boolgetvaluerw()

voidsetvaluerw(

boolvalue)

private

:intmvaluer;

floatmvaluew;

boolmvaluerw;

};

int_tmain(

intargc, _tchar

* argv)

基本上可以滿足要求了,內部類沒有成員,乙個類只佔乙個位元組,比之前面的要節省得多。

儘管用標準語法可以實現「屬性」,但仍有一些不足之處,首先是屬性若傳入有可變引數的函式時會有問題,如下面:

printf("%d", test.valuer);

編譯器識別不出可變引數的具體型別,因此valuer並沒有預設轉換為int,要這樣寫才正確:

printf("%d", (int)test.valuer);

另外乙個問題是「陣列屬性」如何實現,至少我沒有找到更好的辦法,若哪位朋友有好的辦法,不訪分享出來。

如果你確定你的**只會執行在windows上,並且只用vc作為編譯器,那麼就可以用第二種實現。微軟提供了property關鍵字用來支援屬性機制,編譯器會自動將屬性替換為get或set函式,這樣一來屬性就根本不占用任何空間,也沒有任何呼叫開銷。

下面同樣包裝了幾個巨集,不僅實現了普通屬性,也實現了陣列型別的屬性:

#define

property_r(type, propname, getter) __declspec(property(get

=getter)) type propname 

#define

property_w(type, propname, setter) __declspec(property(put

=setter)) type propname

#define

property_rw(type, propname, getter, setter) __declspec(property(get

=getter, put

=setter)) type propname

#define

property_array_r(type, propname, getter) __declspec(property(get

=getter)) type propname

#define

property_array_w(type, propname, getter) __declspec(property(put

=setter)) type propname

#define

property_array_rw(type, propname, getter, setter) __declspec(property(get

=getter, put

=setter)) type propname

有了編譯器的支援,事情的確簡單得多了。

用css屬性實現箭頭

原理 通過擷取 border 的部分拐角實現。l 當寬,高,邊框寬相近 相等 時,改變某一邊的顏色可看到乙個梯形。例一 l 當元素寬高為 0時,且其他邊為透明色時,可以形成乙個三角形。但為了精確定位,讓三角形顯示在合適位置,會使用 position 例如下面所示程式 left right displ...

用屬性來實現封裝

用屬性來實現封裝 屬性是c 引入的一種語言成分,只有很少的語言支援屬性。通過對屬性的讀和寫來保護類中的域。第一種方法體身也是一種好的方式,但用屬性來實現封裝會更方便。現在我們來看乙個例子 using system public class department set public class de...

用C實現複數

在本文中,我將向您展示一種使用c程式語言實現複數的方法。請注意,使用此處提供的 沒有任何保證。複數是乙個數字,例如z,表示z realpart i imaginarypart,其中i是虛數單位,有時用j表示。另外,i i 1,這在查詢兩個複數的乘積 除法時很重要。自然,我們可以將複數實現為結構 de...