当前位置: 首页 > 图文教程 > 开发语言 > VC++ > C 基础:C 类成员属性的一种简洁实现

VC++
在类VC的界面实现中加入目录树
软件换肤技术在 BCB 中的实现
利用非模窗口生成MDI介面
报表输出轻松搞定
Windows 中不规则窗体的编程实现
解说Win32的窗口子类化
使用测试优先方法开发用户界面
一个简单的登录对话框的实现
一个简单的日记本程序
从资源中加载皮肤
一个在RichEdit中添加表情图象的类
ActiveSkin 4.3 软件换肤在VC中的实现
一种另类“关于(About)”对话框的动态显示方法
对话框打印预览及打印
关于如何换肤、子类化的解决方案
制作 MSN、QQ 的消息提示窗口
如何对 BCGControlBarPro 进行换肤
定制个性化的对话框窗口类
改变窗口中的光标形状
更新MFC中的视图,跟踪.NET Framework中的事件

VC++ 中的 C 基础:C 类成员属性的一种简洁实现


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-08-14   浏览: 122 ::
收藏到网摘: n/a

一般来说对于标准C 而言是不存在成员属性这个概念的,以前大家都是用GetXXX/SetXXX来访问或取得数据,好象也没有感觉到任何不便。但是当我们用过C#之类的语言之后,我们总觉得C 这个方式太老土了。于是我们想 ...

一般来说对于标准C 而言是不存在成员属性这个概念的,以前大家都是用GetXXX/SetXXX来访问或取得数据,好象也没有感觉到任何不便。但是当我们用过C#之类的语言之后,我们总觉得C 这个方式太老土了。于是我们想去实现“属性”这个C 语言缺乏的要素。事实上网络上有很多人已经做了这部分工作,实现的方法有很多种,一种是用模板,一种是根据特定语言来写的,如VC(指的是Microsoft实现的C )。但是它们要么很复杂,要么很难记住它的准确用法,嗯我总是喜欢简单的东西,因为太复杂的东东会让我的头脑当机。废话少说,来看看如何实现。
  在实现之前,我必需先探讨一下为什么需要“属性”这个东东。比如说下面雇员这个类:
  class CEmployee
  {
  public:
  int Old; //年龄
  };
  CEmployee employee;
  employee.Old=22;
  int old =employee.Old;
  它有一个成员变量,我们可以直接对它们进行赋值或者读取,但是往往会缺少一个很重要的东东,就是不能对所赋值进行校验,这可是个大问题,比如我们给 Old一个负值,比如-50,提示程序运行时不会有任何错误,但是的确这个成员变量的值在逻辑上是不正确的。于是我们会写上GetOld、SetOld。现在OK了,这个小问题解决了,但新问题来了。我们的类使用者,他们需要重新把他们的代码成写如下的样子,而不是上面的那样。
  CEmployee employee;
  employee.SetOld(22);
  int old =employee.GetOld();
  你的伙伴一定会在写代码时诅咒你写了一个垃圾的类。所以你决定要改变这个现状。很幸运,你是MS的忠实用户,而且你对于MSDN看很仔细,所以你知道可以这样来写
  class CEmployee
  {
  private:
  int m_old;
  public:
  _declspec(property(get= GetOld,put=SetOld))int Old;
  int GetOld(void)
  {
  return m_old;
  }
  void SetOld(int value)
  {
  if( (value >0) && (value <60))
  {
  m_old = value;
  }
  else
  {
  m_old =20;
  }
  }
  };
  Very Good,上面的类完美地完成一个属性所要做的目标,不过还有一点小问题,象我这样比较笨的经常需要查找MSDN才会知道
  _declspec(property(get= GetOld,put=SetOld))int Old;
  这句话的含义,而且我也经常忘记它的具体写法,比如put我常把它写成了set,这总是让我想起了使用C#的美好时光,它是可以写成这个样子的
  public class CEmployee
  {
  private int m_old;
  public int Old
  {
  get
  { return m_old; }
  set
  {
  if(value >0 && value <60)
  {
  m_old = value;
  }
  else
  {
  m_old =20;
  }
  }
  }
  }
  所以我想到可以利用C/C 中强大的武器宏,我们来定义几个宏
  #define PROP(T,X) __declspec(property(get= __get##X,put= __put##X))T X;
  #define GETPROP(T,X) __declspec(property(get= __get##X))T X; //只读属性
  #define SETPROP(T,X) __declspec(property(put= __put##X))T X; //只写属必
  #define GET(T,X) T __get##X(void)
  #define SET(T,X) void __put##X(T value)
  说明一下:T 代表属性的类型如int,double,CString,而X代表属性名称。如果你需要一个只读属性可以使用GETPROP,只写属性则可以使用 SETPORP,然后对应使用一个GET或SET,当然如果你用PROP,而只用了一个GET或SET,也没有错,只是在编译时会告诉你没有一个 __getXXX或__putXXX的方法。然后我们就可以这样来写我们的类。
  class CEmployee
  {
  private:
  int m_old;
  public:
  PROP(int ,Old)
  GET(int,Old)
  {
  return m_old;
  }
  SET(int,Old)
  {
  if( (value >0) && (value <60)) //这里的value你可把它和C#一样当做关键字
  {
  m_old = value;
  }
  else
  {
  m_old =20;
  }
  }
  };
  好了,我们要做的工作已经做完了。当然这种方法还是有很多问题,比如不能使用C#中常用的索引属性,静态属性等等。但是毕竟我们是C 程序员么,呵呵!最后,这种方法只是在VC下有用。