tmyclass =紅色部分就是屬性的宣告,以後可以直接對value進行讀寫,像下面這樣:class
private
fvalue: integer;
funcationgetvalue: integer;
proceduresetvalue(value: integer);
public
property value: integer read getvalue write setvalue;
end;
屬性有幾個顯而易見的好處: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...