http://blog.sina.com.cn/u/1261532101
首先是const 和 reference的使用,这部分内容已经在C语言里说过,但是在C++里又有了一些扩展。
C++允许使用object作为参数传递,但是object有大有小。 比如下面一个object class:
class CBitmap{
public:
CBitmap();
~CBitmap();
private:
const static UINT32 MAX_BUFFER_SIZE = 65536;
UINT32 m_Height;
UINT32 m_Width;
BYTE m_Buffer[MAX_BUFFER_SIZE];
};
如果我们有个函数,是DrawBitmap,那么就有两种不同的声明方式。
========错误的方式========
void DrawBitmap(CBitmap Bitmap);
========正确的方式========
void DrawBitmap(CBitmap & Bitmap);
如果我们使用第一种方式,那么程序就会创建一个临时的CBitmap object,然后把Bitmap拷贝进去,传送给DrawBitmap。这可不是只会拷贝几个字节那么简单,而且CBitmap的所有内容,包括里边的m_Buffer都会拷贝。如果使用reference也就是 "&",就不会有任何操作。如果在DrawBitmap里边不会改变Bitmap的任何状态,也就是不会改变任何属性,那么就最好加上const关键字,最后的 DrawBitmap的声明应该是:
void DrawBitmap(const CBitmap & Bitmap);
这个时候,在DrawBitmap里,只能调用CBitmap中声明为const的函数。让我们来看看代码
class CBitmap{
public:
CBitmap();
~CBitmap();
UINT32 GetHeight(void) const;
void SetHeight(void);
private:
const static UINT32 MAX_BUFFER_SIZE = 65536;
UINT32 m_Height;
UINT32 m_Width;
BYTE m_Buffer[MAX_BUFFER_SIZE];
};
UINT32 CBitmap::GetHeight(void) const
{
return m_Height;
}
void CBitmap::SetHeight(UINT32 Height)
{
m_Height = Height;
}
大家看到了,在 UINT32 GetHeight(void) const; 有个const,意思是这个函数不会改变任何CBitmap里的属性值。由于SetHeight()会改变m_Height,所以不能声明为const. 在DrawBitmap里边,由于参数是const类型,所以只能调用 const的方法。
void DrawBitmap(const CBitmap & Bitmap)
{
Bitmap.GetHeight(); // 正确,没有问题
Bitmap.SetHeight(100); // 错误,Bitmap是const类型
}
值得注意的是,尽量把class的声明中,不改变属性的方法,声明为 const ,这就是所谓的良好的程序风格。
最后,如果在CBitmap里边有另外一个类,比如是CNormalMap,那么如果有个方法用来取得CNormalMap,code如下
class CBitmap {
.....
// 省略
Private:
CNormalMap NormalMap;
public:
CNormalMap GetNormalMap(void);
}
这是一种类做法,但是并没有充分的考虑效率。首先,返回的CNormalMap不是引用,这个是正确的做法,对象拷贝以后,即使改变内容,也不会影响 Class的状态。但是如果我们本来就不打算改变CNormalMap的状态呢?那么这个函数的调用效率就低下了,所以我们一般提供2个函数,代码如下:
class CBitmap {
.....
// 省略
Private:
CNormalMap NormalMap;
public:
CNormalMap GetNormalMap(void);
const CNormalMap & GetStaticNormalMap(void);
}
或者利用C++的函数重载,做如下声明:
class CBitmap {
.....
// 省略
Private:
CNormalMap NormalMap;
public:
CNormalMap GetNormalMap(void);
const CNormalMap & GetNormalMap(void) const;
}
如果我们不打算改变NormalMap的状态,那么就掉用GetStaticNormalMap() 或者 GetNormalMap() 的const调用,这样我们可以充分的利用reference的效率。
===============================================
C+ +真是内容多呀,一个const和reference就讲了一大堆。好了, 继续今天Design Pattern的内容。所谓 Design Pattern,翻译过来就是设计模式,是OO语言的一些基本运用。Aear会讲一些Design Pattern,并且给出在游戏中的可能的运用方式。今天第一课将会介绍Design Pattern中的两个基本概念,Inheritance 和 Delegation.
所谓Inheritance就是继承,我想学过C++的人都知道什么是继承。以上面的CBitmap为例子,如果我们想生成一个CTexture类,并且保留CBitmap的功能,比如GetBitmapHeight什么的,可以这么做:
class CTexture : public CBitmap {
public:
CTexture();
~CTexture();
};
当时还有另外一种方法,并不使用继承,而是把CBitmap当做CTexture的一个成员,这就是Delegation。代码如下:
class CTexture {
public:
CTexture();
~CTexture();
private:
CBitmap InternalBitmap;
public:
UINT32 GetHeight(void) { return InternalBitmap.GetBitmapHeight(); };
};
关于Inheritance和Delegation哪个更好,Aear不想在这里说,因为网上已经有太多的关于这个争论的文章。但是Aear的个人观点是能用Delegation的地方,就不要使用Inheritance。道理很简单,不同class层次的函数调用,很容易使程序员产生混乱。
举个简单的例子: 比如CTexture从CBitmap继承了GetBitmapHeight 方法,但是CTexture又提供了Bitmap的缩小功能,或者是mipmap,所以提供了一个函数 GetTextureHeight()。 只有GetTextureHeight能返回正确的 texture size的内容。 然后一个不明就里的程序员使用这个类,他发现了GetBitmapHeight这个函数,想当然的觉得是这个函数是用来取得texture的大小,那么。。。。。一切都错乱了。
所以在尽可能的情况下使用Delegation,在其他情况,比如一些Design Pattern和Interface的时候,使用Inheritance (纯个人观点).
|
|||||||||||||||||||
原文地址 http://blog.csdn.net/callzjy/archive/2004/01/04/20042.aspx |