2004年10月05日

在VC中使用property关键字

以前从来没有在VC++中使用过,这个关键字。在很多书里面也没有讲过这个关键字。
偶尔在看一个C++ BULIDER一个关于打印端口的程序时,看到其中使用了
_property这样一个关键字。
于是出于本能去MSDN中查找property.在里面看到一些怎么使用该关键字用法:
MSDN中资料:
Microsoft Specific —>

__declspec( property( get=get_func_name ) ) declarator

__declspec( property( put=put_func_name ) ) declarator

__declspec( property( get=get_func_name, put=put_func_name ) ) declarator

This attribute can be applied to non-static “virtual data members” in a class or structure definition. The compiler treats these “virtual data members” as data members by changing their references into function calls.

When the compiler sees a data member declared with this attribute on the right of a member-selection operator (“.” or “->“), it converts the operation to a get or put function, depending on whether such an expression is an l-value or an r-value. In more complicated contexts, such as “+=“, a rewrite is performed by doing both get and put.

This attribute can also be used in the declaration of an empty array in a class or structure definition. For example:

__declspec(property(get=GetX, put=PutX)) int x[];
The above statement indicates that x[] can be used with one or more array indices. In this case, i=p->x[a][b] will be turned into i=p->GetX(a, b), and p->x[a][b] = i will be turned into p->PutX(a, b, i);

//
怎么使用该属性呢?
比如:
一个打印控制类;
打印的最基本的端口有:数据端口(0×378),控制端口(0×37a),状态的端口(0×379),要对那些端口直接读写,除了借助第三方的驱动(如果自己不会写驱动/或者不想写的话,因为在2000/XP中是无法对端口直接读写的)。
于是在一个类中,定义三个缓冲,来存放你读写端口的值(这里利用:port95nt这个免费的第三方的驱动程序可以google下载):
于是类似下面形式
CLpt
{

    //存放寄存器中的内容缓冲
 BYTE m_LPTData;
 BYTE m_LPTControl;
 BYTE m_LPTStatus;
public:
         CLpt();
  ~CLpt();

 //写读数据寄存器
 void write_data_reg(BYTE data)
 { 
        DlPortWritePortUchar(0X378,data);

 }
 BYTE read_data_reg()
      {
          return DlPortReadPortUchar(0X378,data);

 }

       //其他的具体内容类似就不写了。
 //写读控制寄存器
 void write_control_reg(BYTE control);
 BYTE read_control_reg();

 //写读状态寄存器
 void write_status_reg(BYTE status);
 BYTE read_status_reg();
public:

 ////在这里像MSDN中说的一样使用property这个关键子。
        //这样就可以通过data,status,control这写属性,来访问(读/写)端口的内容了。是不是感觉比较方便呢。
 //当用拥护: i = CLpt::Data 它将调用CLpt::read_data_reg();
 //当用户: CLpt::Data = i; 它将调用CLpt::write_data_reg(i);
   __declspec(property(get=read_data_reg, put=write_data_reg)) BYTE Data;
   __declspec(property(get=read_status_reg, put=write_status_reg)) BYTE Status;
   __declspec(property(get=read_control_reg, put=write_control_reg)) BYTE Control;

};

比如 :
CLpt* m_plpt =new CLpt;
往里面写入数据0×56就可以这样:m_plpt->Data =  0×56;
要读出里面的数据就可以这样:BYTE m_bdata =m_lpt->Data; //^_^这样感觉方便多了。