C++中的属性

来源:互联网 发布:西安天网软件拖欠工资 编辑:程序博客网 时间:2024/06/06 02:30

C++中的属性


 C#中有属性(Property),而C++中却没有,其实属性对于C++而言也是非常重要的,请往下看。


 什么是属性

 属性就像那些可以存储数据的变量,但在从它们中读写数据时会引发事件,换句话来说,属性就是一个有互作用的变量,自我更新,并在读写其自身时产生不同的值。
 使用像C#这样包含属性的语言非常容易编写一个类,但对C++来说似乎就不太可能了,因为C++的编译器不支持C#那种形式的属性。正因为此,本文就是要介绍如何编写带有像C#中属性的C++类。


 为什么属性很重要

 如果你需要编写一个代表人物的对象,这个对象可能包含以下数据:全名、年龄、出生年月、性别。如果用C++来编写,代码如下:


class Person {
public:
   Person( ){}
   virtual ~Person( ){}

private:    //数据成员

   char m_fName[20];
   char m_lName[20];

   UINT m_YearOfBirth;
   bool m_bGender;
};


 注意:在大多数情况中,不能为了可直接使用,就定义一个数据成员为public,因为数据成员应由对象内实现的业务逻辑来维护。

 如果需要设置或读取m_bGender的值,就可能要实现以下的方法:


class Person {
public:
   Person( ){}
   virtual ~Person( ){}

   void SetGender(bool bGender) {m_bGender = bGender;}
   bool GetGender() {return m_bGender;}

private:    //数据成员

   char m_fName[20];
   char m_lName[20];

   UINT m_YearOfBirth;
   bool m_bGender;
};


 这种方法的弊端在于必须要事先知道其名称与用途,要是使用属性,就简单多了,所需了解的只是属性名而已,且单个属性能支持不同的数据类型,也就是说,在上例中,可让Gender接受字符串或布尔类型,如下所示:


Person.Gender = "Male";

或:

Person.Gender = true;


 属性声明

 现在,来看如何编写属性,就从Gender属性开始吧:


class Person {
public:
   Person( ){}
   virtual ~Person( ){}

   Begin_Property(char*,Gender)
      __get(char*,Gender)
      _set(char*);

      _get(bool);
      _set(bool);

      __release(Gender)
   End_Property(Gender)

private:    //数据成员

   char m_fName[20];
   char m_lName[20];

   UINT m_YearOfBirth;
   bool m_bGender;
};


 代码中使用Begin_Property宏开始定义一个属性,它接受两个参数:属性数据类型及属性名。因为Gender属性是一个字符串属性,所以它应为char *。之后,还需要声明事件get()与set(),用于引发事件,如下所示:


// 这会引发 _set(bool) 事件
Person.Gender = true;
// 这会引发 _get(bool) 事件
bool gender = Person.Gender ;
// 这会引发 _set(char*) 事件
Person.Gender = "Male";
// 这会引发 _get(char*) 事件
printf("Gender :%s/n",(char*)Person.Gender);


 _get与_set是两个宏,分别接受一个参数,而这个参数代表了属性可接受的数据类型,你可看到_get与_set事件的数据类型独立于属性的数据类型,换句话来说,尽管Gender属性的数据类型为char *,但它也可接受布尔类型。
 最后两个宏为:_release,其释放它分配的内存;End_Property,其结束属性声明,两个宏都接受属性名为参数。


 属性的实现

 声明属性后,需要实现set()与get()了,请看如下的代码:


……
Begin_Property(char*,Gender)
   __get(char*,Gender)
   _set(char*)
   {
      //某些代码
      return Gender;
   }

   _get(bool)
   {
      //某些代码
      return iValue;
   }
   _set(bool)
   {
      //某些代码
      return iValue;
   }

   __release(Gender)
End_Property(Gender)
……


 在此可用实现宏来实现它,在讲述如何使用这些宏之前,先解释一下两点问题:__get宏是什么及为什么set()要返回一个值。在__get(char *)中,仅是返回一个指针:“return Gender”,它是默认的getter属性,因为“Gender”是一个char *属性,所以应这样使用它:“__get(char *,Gender)”。
 来看第二个问题,为什么set()要像get()那样返回一个值呢?简单来说,在C++中,set()能扮演get()的角色,请看下面的代码:


bool bGender = Person.Gender = true;


 现在,可使用Imp_set及Imp_get两个宏来实现Gender属性了,两个宏都接受三个参数:数据类型、类名及属性名,如下:


Imp_set(char*,Person,Gender)
{
   PROPERTY_PROLOGUE(Person,Gender)

   if (!Gender) Gender = new char[7];

   if (strlen(iValue)<6 )
   {
      int result;
      if ((result=strcmp(iValue,"Male"))==0)
         pThis->m_bGender = true;
      else
      {
         if ((result=strcmp(iValue,"Female"))==0)
         pThis->m_bGender = false;
      }

      if(result==0) strcpy(Gender,iValue);
   }
   return Gender;
}

Imp_set(bool,Person,Gender)
{
   PROPERTY_PROLOGUE(Person,Gender)

   if (!Gender) Gender = new char[7];

   if (pThis->m_bGender = iValue)
      strcpy(Gender,"Male");
   else
      strcpy(Gender,"Female");

   return (bool)iValue;
}

Imp_get(bool,Person,Gender)
{
   PROPERTY_PROLOGUE(Person,Gender)
   return pThis->m_bGender;
}


 因为set()与get()不能直接访问类成员,所以要使用PROPERTY_PROLOGUE宏,它定义了一个指向属性类的指针:“pThis”,如上所示。
 同时,在类的结尾处,需要释放内存及所有分配的资源,这由__release宏完成。__release是默认的释放宏,它的代码如下:


if (Gender)
{
   delete Gender;
   Gender = NULL;
}


 另外,也可使用_release及Imp_release来实现释放事件,如下所示:


Imp_release(Person,Gender)
{
   //在此释放所有分配的资源
}


 

         示例工程下载:Properties_Demo.zip

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 老板让写的报道没有当天写完怎么办 洛奇英雄传镶嵌有微章的时装怎么办 上午12点用24小时制怎么办 三分钟看懂捷信个人贷款怎么办 精神不正常的父亲到单位闹怎么办 母亲和父亲一直和我闹怎么办 儿子拿了父亲的钱买手机怎么办 电动车骑的慢的时候车头打漂怎么办 二晓啊相公太爱我了怎么办全文免费 车牌被套牌了又有违章怎么办 高中生只学好主课副科学不好怎么办 母泰迪怀孕23天了不吃饭怎么办 媳妇一再触碰我的底线怎么办 发票商品编码好多选错了分类怎么办 吃了用福尔马林泡的食物怎么办 没大没小说话不尊重人的孩子怎么办 升级安卓8.0后app闪退怎么办 业主装门占用消防通道物业怎么办? 想改名字派出所不给改怎么办 物业不给地热打压影响装修怎么办 pos机pin效码验证错误怎么办 苹果下载东西要发验证码怎么办 接口断在了丝扣里面怎么办 政府下了一张关停取缔单怎么办 微信运动数据不刷新了怎么办 邻居霸占我的土地不还我该怎么办 双层水浴式杀菌锅阀门坏了怎么办 通下水管的钢丝断水管里了怎么办 塑料水管与水阀连接处漏水怎么办 介质流向标识管道温度太高怎么办 雪碧里气体太多瓶子涨得要炸怎么办 餐厅不清洗油烟管道物业该怎么办 用完权健洁净宝后奇痒的厉害怎么办 老房子铸铁暖气管从外锈蚀了怎么办 德意壁挂炉补水多了水压过高怎么办 新空调的散热片铜管漏了怎么办 猪舍被别人推掉漏电电到人怎么办? 网上买的燃气灶连接用软管怎么办 哈弗h3后减振器上支架坏了怎么办 汽车用收录机电机皮带断了怎么办 大便太粗把马桶堵了怎么办