zoukankan      html  css  js  c++  java
  • C++中的属性

    C++中的属性

    首先我们来看一下C#中的属性

    c#中的字段通常是 private,内部使用。
    属性是 public 或 protected,对外公开,属性通过 get set 访问器对字段提供安全、有效范围等保护。
    讲概念可能不好讲,下面来看一个例子吧!(最简单的)
    class Program
    {
    private int field1; //这个field1就是字段
    public int Field1 //这个Fileds1就是属性
    {
    get{return field1;}
    set{field1=value;}
    }
    }//因为字段的访问修饰符为private外部不能访问它,但可以定义属性为public来访问。

    http://blog.csdn.net/xieqidong/article/details/3265199
     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)
    {
       //在此释放所有分配的资源
    }

  • 相关阅读:
    解决ajax 发送post 请求时csrf_token 问题
    pip 常用命令
    mac 查看端口的使用情况
    使用from __future__ import unicode_literals
    git 使用
    django rest_framework
    Apache JMeter 接口压力测试
    HTTP 协议
    自定义异步非阻塞web框架
    WebSocket
  • 原文地址:https://www.cnblogs.com/hualalasummer/p/3705255.html
Copyright © 2011-2022 走看看