用 C# 或者 Borland C++ Builder 的时候会遇见“property”这个东西,可以控制读写方式。标准 C++ 并没有这个概念,那么我们能否在纯 C++ 中使用这个功能呢?当然可以。下面是本人独立完成的一个实现方法:
#include <iostream>
using namespace std;
typedef enum {READONLY, READWRITE} RW_Right;
template <class _Class /* 包含该属性的类 */ ,
typename _Ty /* 该属性的类型 */,
RW_Right = READWRITE /* 该属性的权限:默认为读写 */ >
class Property
{
public:
typedef _Ty* (_Class::*Getter)(void);
typedef void (_Class::*Setter)(const _Ty&);
public:
Property(_Class& _src /* 目标对象*/,
const Getter _getter /* 取值函数 */,
const Setter _setter /* 赋值函数 */)
:m_src(_src), m_getter(_getter), m_setter(_setter)
{}
operator _Ty&() /* 返回 lvalue */
{
return *(m_src.*m_getter)(); /* 可以直接对原始数据赋值 */
}
operator const _Ty&() const
{
return *(m_src.*m_getter)();
}
_Ty& operator=(const _Ty& _value) /*返回一个 lvalue */
{
(m_src.*m_setter)(_value);
return *(m_src.*m_getter)();
}
private:
_Class& m_src; /* 保存宿主类信息 */
Getter m_getter; /* 宿主取值函数 */
Setter m_setter; /* 宿主赋值函数 */
Property(); /* 必须在宿主类建立的同时初始化 */
Property(const Property&);
Property& operator=(const Property&);
};
template <class _Class,typename _Ty>
class Property <_Class, _Ty, READONLY/*只读属性的特化模板*/>
{
public:
typedef _Ty* (_Class::*Getter)(void);
public:
Property(_Class& _src, const Getter _getter)
:m_src(_src), m_getter(_getter)
{}
operator const _Ty() const /* 只能返回 rvalue */
{
return *(m_src.*m_getter)();
}
private:
_Class& m_src;
Getter m_getter;
Property();
Property(const Property&);
Property& operator=(const Property&);
_Ty& operator=(const _Ty& _value); /* 禁止赋值操作 */
};
class MyClass
{
public:
int* get_count()
{
cout << "Getting property" << endl;
return &m_count;
}
void set_count(const int& _count)
{
cout << "Setting property" << endl;
m_count = _count;
}
public:
MyClass()
:Count(*this, &MyClass::get_count, &MyClass::set_count)
{}
Property<MyClass, int, READWRITE> Count;
private:
int m_count;
};
int main(int argc,char* argv[])
{
MyClass mc;
mc.Count = 2;
int j = mc.Count;
cout << j << endl;
return 0;
}
以上测试程序编译会出现 warning
warning C4355: “this” : 用于基成员初始值设定项列表
不用担心。 VC 7.1 编写调试,本人版权所有,有意见建议请发短消息。
本文地址:http://com.8s8s.com/it/it1478.htm