C++ Builder和托管C++中属性的通用建议:
1.类的任何成员变量尽量都对应相应的属性.外部不能访问的成员变量用protected或者private属性.
2.类的任何成员变量尽量通过属性访问.不管是类内部访问自己的成员变量还是类外部访问类内部的成员变量.
3.除属性对应的函数,构造函数,析构函数等特殊的函数外,类的内部访问自己的成员变量时尽量用属性.
4.属性尽量用于简单的数据类型或者简单的类.即属性的类型最好是简单的数据类型或者简单的类.
5.C++Builder中:复杂类型的属性,用指针或者对象的应用.
托管C++中:复杂类型的属性,用函数代替.建议用Get和Set打头对应于属性的读和写.
注:这一条有时候我们容易忽视,是因为我很容易忘记C++中的默认拷贝构成函数,在函数中当参数是复杂对象时,也存在类似的问题.
C++Builder中对第5条的解释:详细源码见示例工程
//SampleClassUnit.H 文件
//---------------------------------------------------------------------------
#ifndef SampleClassUnitH
#define SampleClassUnitH
//---------------------------------------------------------------------------
#include <Classes.hpp>
//---------------------------------------------------------------------------
class TBasic
{
private: // User declarations
public: // User declarations
int m_iNum;
int * m_pNum;
public: // User declarations
__fastcall TBasic();
__fastcall ~TBasic();
};
//---------------------------------------------------------------------------
class THeritor
{
private: // User declarations
TBasic __fastcall GetBasicObject();
TBasic * __fastcall GetBasicPointer();
TBasic & __fastcall GetBasicReference();
public: // User declarations
TBasic m_Basic;
TBasic * m_pBasic;
TBasic m_BasicReference;
public: // User declarations
__fastcall THeritor();
__fastcall ~THeritor();
public:
__property TBasic BasicObject = { read=GetBasicObject};
__property TBasic * BasicPointer = { read=GetBasicPointer};
__property TBasic & BasicReference = { read=GetBasicReference};
};
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#endif
//SampleClassUnit.cpp文件
//---------------------------------------------------------------------------
#pragma hdrstop
#include "SampleClassUnit.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
__fastcall TBasic::TBasic()
{
m_iNum = 10;
m_pNum = new int(100);
}
__fastcall TBasic::~TBasic()
{
delete m_pNum;
m_pNum = NULL;
}
//---------------------------------------------------------------------------
__fastcall THeritor::THeritor()
{
m_pBasic = new TBasic();
}
__fastcall THeritor::~THeritor()
{
delete m_pBasic;
m_pBasic = NULL;
}
//---------------------------------------------------------------------------
TBasic __fastcall THeritor::GetBasicObject()
{
return m_Basic;
}
TBasic * __fastcall THeritor::GetBasicPointer()
{
return m_pBasic;
}
TBasic & __fastcall THeritor::GetBasicReference()
{
return m_BasicReference;
}
//---------------------------------------------------------------------------
//测试函数
void __fastcall TSampleForm::Button1Click(TObject *Sender)
{
//指针属性
if (m_pHeritor != NULL)
{
TBasic * pBasic = m_pHeritor->BasicPointer;
int iNum = pBasic->m_iNum;
RichEdit1->Lines->Add("m_iNum=" + IntToStr(iNum));
if (pBasic->m_pNum != NULL)
{
int ipNum = *(pBasic->m_pNum);
RichEdit1->Lines->Add("m_pNum=" + IntToStr(ipNum));
}
else
{
RichEdit1->Lines->Add("m_pNum=NULL!");
}
}
}
//---------------------------------------------------------------------------
void __fastcall TSampleForm::Button2Click(TObject *Sender)
{
//引用属性
if (m_pHeritor != NULL)
{
TBasic * pBasic = &(m_pHeritor->BasicReference);
int iNum = pBasic->m_iNum;
RichEdit1->Lines->Add("m_iNum=" + IntToStr(iNum));
if (pBasic->m_pNum != NULL)
{
int ipNum = *(pBasic->m_pNum);
RichEdit1->Lines->Add("m_pNum=" + IntToStr(ipNum));
}
else
{
RichEdit1->Lines->Add("m_pNum=NULL!");
}
}
}
//---------------------------------------------------------------------------
void __fastcall TSampleForm::Button3Click(TObject *Sender){
//对象属性
if (m_pHeritor != NULL)
{
TBasic * pBasic = &(m_pHeritor->BasicObject);
int iNum = pBasic->m_iNum;
RichEdit1->Lines->Add("m_iNum=" + IntToStr(iNum));
if (pBasic->m_pNum != NULL)
{
int ipNum = *(pBasic->m_pNum);
RichEdit1->Lines->Add("m_pNum=" + IntToStr(ipNum));
}
else
{
RichEdit1->Lines->Add("m_pNum=NULL!");
}
}
}
//---------------------------------------------------------------------------
void __fastcall TSampleForm::Button4Click(TObject *Sender)
{
//指针
if (m_pHeritor != NULL)
{
TBasic * pBasic = m_pHeritor->m_pBasic;
int iNum = pBasic->m_iNum;
RichEdit1->Lines->Add("m_iNum=" + IntToStr(iNum));
if (pBasic->m_pNum != NULL)
{
int ipNum = *(pBasic->m_pNum);
RichEdit1->Lines->Add("m_pNum=" + IntToStr(ipNum));
}
else
{
RichEdit1->Lines->Add("m_pNum=NULL!");
}
}
}
//---------------------------------------------------------------------------
void __fastcall TSampleForm::Button5Click(TObject *Sender)
{
//引用
if (m_pHeritor != NULL)
{
TBasic * pBasic = &(m_pHeritor->m_BasicReference);
int iNum = pBasic->m_iNum;
RichEdit1->Lines->Add("m_iNum=" + IntToStr(iNum));
if (pBasic->m_pNum != NULL)
{
int ipNum = *(pBasic->m_pNum);
RichEdit1->Lines->Add("m_pNum=" + IntToStr(ipNum));
}
else
{
RichEdit1->Lines->Add("m_pNum=NULL!");
}
}
}
//---------------------------------------------------------------------------
void __fastcall TSampleForm::Button6Click(TObject *Sender)
{
//对象
if (m_pHeritor != NULL)
{
TBasic * pBasic = &(m_pHeritor->m_Basic);
int iNum = pBasic->m_iNum;
RichEdit1->Lines->Add("m_iNum=" + IntToStr(iNum));
if (pBasic->m_pNum != NULL)
{
int ipNum = *(pBasic->m_pNum);
RichEdit1->Lines->Add("m_pNum=" + IntToStr(ipNum));
}
else
{
RichEdit1->Lines->Add("m_pNum=NULL!");
}
}
}
//---------------------------------------------------------------------------
托管C++中:
当你的类用于WebService中的时候,当WebService客户端向服务器请求该类的一个对象时,服务器会把该类的相关数据格式化为XML文件传到客户端,其中包括所有属性的值.如果属性包括复杂类型时,可能导致属性中有对象,对象中又有属性,以至于嵌套很深,服务器格式化对象数据为XML文档就要花费很长时间,
1.属性最好不要用于返回复杂对象上.如属性得到的是自定义的对象,或者一些带有指针的对象.这种情况最好是返回对象的指针或者对象的应用的属性.因为当返回对象的属性,会调用对象的拷贝构造函数,一来系统开销大,二来当通过属性得到的对象的副本在超出其作用域时析构时可能调用你自己的析构函数将对象中的指针所指的对象析构调.