下载 > 资源分类 >  开发技术 >  C++ > 在c++中实现属性

在c++中实现属性

2004-07-27 上传大小:17KB
在C++中实现属性
本文译自http://www.codeguru.com/cpp_mfc/Property.html的Implementing a Property in C++
以下是译文
本文由Emad Barsoum投稿。
开发测试环境:Visual C++ 7.0, Windows XP sp1, Windows 2000 sp3
摘要
本文试着在C++中不使用任何扩展技术模
拟C#(或其他语言)中的属性特征。大多数在C++实现属性的库和编译器使用扩展技术,如Managed C++或C++ Builder,或者他们使用如通常函数的set和get方法,但那不是属性。
详述
我们首先看一下什么是属性。一个属性表现为一个字段或者成员变量,但它通过read和write方法或者get和set方法暗中操作变量。
例如,若存在类A和它的属性Count,我可以写如下的代码:
 A foo;
 Cout << foo.Count;
实际上Count调用它的get函数返回当前的变量值。你可以将属性定为只读(你可以读取它但不能修改它)、只写或者可读写,这就是使用属性而不直接使用变量的的一个最大好处了。好了,让我们开始来实现它:
我们需要能做如下的事:
 int i = foo.Count;  //--调用get函数得到值
 foo.Count = i;  //-- 调用set函数设定值
因此,很明显的我们需要重载 = 操作符使其能设定变量的值,同时也要重载该属性的返回值(在下面我们将会看到的)。
我们将实现一个称为property的类,它做的就像一个属性,声明如下:
template <typename Container, typename ValueType, int nPropType>
class property {}
这个模板类表示的是我们的属性。Container是我们要在其中包含属性的类变量,set和get方法以及属性的类的类型。ValueType是内部变量即要定义的属性的类型,nPropType定义属性的读写标志:只读、只写或可读写。
现在我们需要一个指向从包含属性的类Container到属性类property的set和get方法的指针,同时重载 = 操作符以使得属性能象变量起那样作用。现在我们来看property类的全部定义
#define READ_ONLY 1
#define WRITE_ONLY 2
#define READ_WRITE 3
template <typename Container, typename ValueType, int nPropType>
class property
{
public:
property()
{
  m_cObject = NULL;
  Set = NULL;
  Get = NULL;
}

//-- 将m_cObject指向包含属性的container类 --
void setContainer(Container* cObject)
{
  m_cObject = cObject;
}
//-- 设定可改变属性值的set成员函数 --
void setter(void (Container::*pSet)(ValueType value))
{
  if((nPropType == WRITE_ONLY) || (nPropType == READ_WRITE))
    Set = pSet;
  else
    Set = NULL;
}
//-- 设定可检索属性值的get成员函数 --
void getter(ValueType (Container::*pGet)())
{
  if((nPropType == READ_ONLY) || (nPropType == READ_WRITE))
    Get = pGet;
  else
    Get = NULL;
}
//-- 重载 = 号操作符使其能用set成员设定属性值--
ValueType operator =(const ValueType& value)
{
  assert(m_cObject != NULL);
  assert(Set != NULL);
  (m_cObject->*Set)(value);
  return value;
}
//-- 使属性类能转换为内部类型成为可能--
operator ValueType()
{
  assert(m_cObject != NULL);
  assert(Get != NULL);
  return (m_cObject->*Get)();
}
private:
  Container* m_cObject;  //-- 指向包含属性的类模块 --
  void (Container::*Set)(ValueType value);
                         //-- 指向set成员函数的函数指针 --
  ValueType (Container::*Get)();
                         //-- 指向get成员函数的函数指针 --
};

现在让我们来一段一段地看这些代码:

在下面的代码中,仅仅将Container指针指向一个有效的包含属性的实例。
void setContainer(Container* cObject)
{
  m_cObject = cObject;
}
下面的代码,设定指针指向包含属性的类中的set和get成员函数,其set和get成员函数度有,唯一的限制即set成员函数必须有一个ValueType型的参数并无返回值,get成员函数没有参数,但要返回ValueType型值。

//-- 设定可改变属性值的set成员函数 --
void setter(void (Container::*pSet)(ValueType value))
{
  if((nPropType == WRITE_ONLY) || (nPropType == READ_WRITE))
    Set = pSet;
  else
    Set = NULL;
}
//-- 设定可检索属性值的get成员函数 --
void getter(ValueType (Container::*pGet)())
{
  if((nPropType == READ_ONLY) || (nPropType == READ_WRITE))
    Get = pGet;
  else
    Get = NULL;
}
在如下的代码中,第一部分是 = 操作符的重载,它调用包含属性的类中的set函数设定其属性的值。第二部分则为了使整个属性类象ValueType类型一样起作用,所以它返回包含属性的类中get函数的返回值。

//-- 重载 = 号操作符使其能用set成员设定属性值--
ValueType operator =(const ValueType& value)
{
  assert(m_cObject != NULL);
  assert(Set != NULL);
  (m_cObject->*Set)(value);
  return value;
}
//-- 使属性类能转换为内部类型成为可能--
operator ValueType()
{
  assert(m_cObject != NULL);
  assert(Get != NULL);
  return (m_cObject->*Get)();
}

现在我们来看看怎样使用它:
如下所示,在PropTest类中定义了一个叫做Count的简单属性。Count的实际值将保存到或检索之在PropTest的私有成员变量"m_nCount"中,通过PropTest的get和set方法。get和set方法可以使用任何的变量名字,只需他们的地址能被传递到property类中,如下面的PropTest构造函数里面的代码般,代码行" property<PropTest, int, READ_WRITE> Count; "让我们在PropTest中得到可读写的int型的Count属性。现在你可以使用如一般的成员变量般使用使用Count属性了,但实际上你是间接地调用它set和get方法。

要使Count属性能成功工作,必须先在PropTest的构造函数里面对其进行初始化。

class PropTest
{
public:
  PropTest()
  {
    Count.setContainer(this);
    Count.setter(&PropTest::setCount);
    Count.getter(&PropTest::getCount);
  }
  int getCount()
  {
    return m_nCount;
  }
  void setCount(int nCount)
  {
    m_nCount = nCount;
  }
  property<PropTest,int,READ_WRITE> Count;


private:
  int m_nCount;
};

如下
...展开收缩
综合评分:4.5(10位用户评分)
直接下载 开通VIP会员 免积分下载

评论共有0条

评论资源

您不能发表评论,可能是以下原因:

登录后才能评论

待评论资源
 

热门专辑

关闭
img

spring mvc+mybatis+mysql+maven+bootstrap 整合实现增删查改简单实例.zip

CSDN VIP年卡 4000万程序员的必选现在开通,立省522元
下载
img

在c++中实现属性

会员到期时间:剩余下载个数:
VIP下载

积分不足!

资源所需积分 当前拥有积分
您可以选择
开通VIP年卡
4000万
程序员的必选
600万
绿色安全资源
现在开通
立省522元
或者
购买C币兑换积分 C币抽奖
img
资源所需积分 当前拥有积分
VIP年卡全年1200个资源免积分下载促销价78元,开通立省522元
下载
下载

兑换成功

你当前的下载分为234开始下载资源
你还不是VIP会员
开通VIP会员权限,免积分下载
立即开通

你下载资源过于频繁,请输入验证码

你下载资源过于频繁,请输入验证码

您因违反CSDN下载频道规则而被锁定帐户,如有疑问,请联络:webmaster@csdn.net!

举报

若举报审核通过,可奖励20下载分

  • 举报人:
  • 被举报人:
  • 举报的资源分:
  • *类型:
  • *详细原因: