C++でプロパティ的なマクロ[VC++,C++Builder]


アクセサをその都度記載するのがめんどくさいので、探してみた結果、下記のところに素晴らしいものがあったので
>http://www.moonmile.net/blog/archives/3557

少し変更してみました。
マクロなので、使用するときは自己責任で十分気をつけてください。

時々修正しています。変更した内容は最下部に書いておきます。
##VisualC++編

```cpp:VisualC++
class TestClass{

private:
#define PROPERTY( _P_TYPE ,_P_MEMBER ) \
private : _P_TYPE m_##_P_MEMBER ; \
public : \
__declspec (property ( get= get##_P_MEMBER , put= set##_P_MEMBER )) _P_TYPE _P_MEMBER ; \
_P_TYPE get##_P_MEMBER () const{ return m_##_P_MEMBER ; } \
void set##_P_MEMBER (const _P_TYPE &value ){ m_##_P_MEMBER = value ; }
  public :
///ここからプロパティ内容を登録する部分
  PROPERTY(int, x); //使用例
  PROPERTY(float , y); //使用例
///ここまでにプロパティ内容を登録完了させる。
///↓PROPERTYの使用を解除
#undef PROPERTY

public:TestClass(){};///コンストラクタ
};
/// 例えば
/// PROPERTY(int, test);
/// を登録した場合、
/// private : int m_test;
/// public : __declspec (property ( get= gettest , put= settest )) int test ;
/// int gettest () const{ return m_test ; }
/// void settest ( const int &value ){ m_test = value ; }
/// と記載したことと同じ意味になります。

/// リンク先に記載がありますがCStringでの使用等、うまく動作しない場合があります。
```

```cpp:使用例_VisualC++
class TestClass{

private:
#define PROPERTY( _P_TYPE ,_P_MEMBER ) \
private : _P_TYPE m_##_P_MEMBER ; \
public : \
__declspec (property ( get= get##_P_MEMBER , put= set##_P_MEMBER )) _P_TYPE _P_MEMBER ; \
_P_TYPE get##_P_MEMBER () const{ return m_##_P_MEMBER ; } \
void set##_P_MEMBER (const _P_TYPE &value ){ m_##_P_MEMBER = value ; }
public:
	PROPERTY(int, x); ///プロパティ
#undef PROPERTY
	int y; ///プロパティではない
public:TestClass(){};
};
void TestFunction(int &val){ val = 2; }///参照渡し関数

//---省略
TestClass *test = new TestClass();
test->x = 1;///OK
test->y = 1;///OK
TestFunction(test->x);///エラー
TestFunction(test->y);///OK
int *px = &test->x;///エラー
int *py = &test->y;///OK
delete test;
```
##C++BUILDER編
```cpp:C++BUILDER
class TestClass{
private:
#define PROPERTY( _P_TYPE ,_P_MEMBER ) \
private: _P_TYPE var_##_P_MEMBER;\
public:\
__property _P_TYPE _P_MEMBER = {read = Get##_P_MEMBER, write = Set##_P_MEMBER};\
private: \
void __fastcall Set##_P_MEMBER (const _P_TYPE &val) { \
var_##_P_MEMBER = val; \
} \
_P_TYPE __fastcall Get##_P_MEMBER() const{ \
return var_##_P_MEMBER;\
}
public:
	PROPERTY(int, x);
	PROPERTY(float, y);
#undef PROPERTY
private:
public:///C++BUILDERの場合、undefの外でpublicを再度宣言しないと
/// y がアクセスできなくなる場合があり、
///さらにpublic:のみだと整形したときにpublic:が削除されるので、
///一旦private:を入れた後にpublic:を宣言したほうが良い。
__fastcall TestClass(){};
}
```

```cpp:使用例__C++Builder
class TestClass{
private :
#define PROPERTY( _P_TYPE ,_P_MEMBER ) \
private: _P_TYPE var_##_P_MEMBER;\
public:\
__property _P_TYPE _P_MEMBER = {read = Get##_P_MEMBER, write = Set##_P_MEMBER};\
private: \
void __fastcall Set##_P_MEMBER (const _P_TYPE &val) { \
var_##_P_MEMBER = val; \
} \
_P_TYPE __fastcall Get##_P_MEMBER() const{ \
return var_##_P_MEMBER;\
}
public:
	PROPERTY(int, x); ///プロパティ
#undef PROPERTY
private:
public:__fastcall TestClass(){};
	int y; ///プロパティではない
}

void TestFunction(int &val){ val = 2; }///参照渡し関数
//---省略
TestClass *test = new TestClass();
test->x = 1;///OK
test->y = 1;///OK
TestFunction(test->x);///エラー!
TestFunction(test->y);///OK
int *px = &test->x;///エラー
int *py = &test->y;///OK
delete test;
```

```cpp:修正点
///引数部分を変更 16/05/17
void set##_P_MEMBER ( _P_TYPE value ){ m_##_P_MEMBER = value ; }
void set##_P_MEMBER ( const _P_TYPE &value ){ m_##_P_MEMBER = value ; }
///Getの頭のconstを削除。 16/05/18
const _P_TYPE __fastcall Get##_P_MEMBER() const{ \
return var_##_P_MEMBER;\
_P_TYPE __fastcall Get##_P_MEMBER() const{ \
return var_##_P_MEMBER;\