游戏开发论坛

 找回密码
 立即注册
搜索
查看: 22647|回复: 15

C++基本功和 Design Pattern系列(1) - Inheritance VS Delegation

[复制链接]

27

主题

179

帖子

259

积分

中级会员

Rank: 3Rank: 3

积分
259
发表于 2006-10-25 14:14:00 | 显示全部楼层 |阅读模式
======================================================
大家请把我的文章当参考,详细内容  还请参照 权威书籍
<c++ programming language>如果文中有错误和遗漏,
请指出,Aear会尽力更正, 谢谢!
======================================================

首先恭喜C++版开张,这样Aear又多了一个可以发表废话的地方。基本上C++基本功系列会是一个比较长的东西,因为C++和OO的内容太多,太难说的清楚。Aear本人也不能保证所有的说的都正确,但是能发上来的内容都参照过 ISO, <<The C++ programming language>>,以及其他的参考资料。

其次,为什么Aear继续写基本语言的东西? Aear本来想写一些DirectX啊,shader啊,game开发理论什么的。不过想来想去,还是觉得不要误导大家的好。主要原因是,看aear文章的大部分都是非专业人士,想走进游戏开发这个领域。根据Aear的个人经验,游戏开发最重要的是基本功,而不是DirectX和OpenGL这些API的使用方法。下面列出的是我认为对游戏开发比较有用的东西,从重要到不重要排列。
       1. 英语 (没办法,几乎所有用的文档,都是英文的,不过也是最可以忽略的)
       2. 基础物理学和数学 (这个不用我说了吧)
       3. C/C++和其他程序设计语言 (这个没的说,基本工,至少1到3年的时间能有小成)
       4. 数据结构,算法理论 (几乎游戏开发天天用)
       ===========这里往上是基础,Aear认为是进入这个行业的必然条件=========
       5. 计算机图形学,计算机网络
       6. 高等数学,空间几何,微积分等等
       7. Windows 体系结构,计算机结构,软件工程理论
       8. 开发环境
       9. API (DirectX OpenGL)等

5到7一般是大学计算机专业的必学内容,如果能够有扎实的1到8的基础,DirectX和OpenGL应该花1个星期学就够了,1个月就能精通。

根据Aear的面试经验,程序设计50%,其中30%数据结构内容,从基本链表到高等图论内容全考。 20%数学基础,10%优化,其他还有一些算法分析等等。基本上别人问都不问DirectX和OpenGL,当然也是我拿了Demo去的缘故。还有我的经验只做参考,请大家根据自己的实际情况来决定学习内容和面试准备。下面让我们顺便看看Blizzard对于程序员的要求:

Requirements

    * Strong C/C++ and PC programming skills.
    * Minimum of 2 years experience programming at least one title that has already shipped.
    * A passion for games and game development.
    * Good communication skills.
    * Bachelor's degree in Computer Science or a related field.

Plusses

    * Graphics or sound programming experience.
    * Strong math background.
    * Experience in game design.
    * Knowledge of Win32 and DirectX API's.
    * Prior work experience on an MMORPG.

看到没,DirectX排倒数第2,还是plus里的,不会根本无伤大雅。很多公司都和blizzard差不多,只要你基本工扎实,学DirectX很快的。

=====================分割线=====================
好了,废话不多说,让我们开始吧。首先是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 (纯个人观点).

好了,今天就说这么多了。作为开场第一章内容也够了吧。还有部分文章都发在我的BLOG上,大家有空去坐坐 http://blog.sina.com.cn/u/1261532101 下次见。

8

主题

716

帖子

716

积分

高级会员

Rank: 4

积分
716
发表于 2006-10-25 18:04:00 | 显示全部楼层

Re:C++基本功和 Design Pattern系列(1) - Inheritance VS Delegation

Aear辛苦了
大家有空去看《More/Effective C++》和《More/Exception C++》吧

121

主题

2029

帖子

2034

积分

金牌会员

Rank: 6Rank: 6

积分
2034
QQ
发表于 2006-10-25 20:01:00 | 显示全部楼层

Re:C++基本功和 Design Pattern系列(1) - Inheritance VS Delegation

自从有了concept,我头不昏了,眼不花了,写程序也有劲了!

2

主题

18

帖子

18

积分

新手上路

Rank: 1

积分
18
发表于 2006-10-27 10:38:00 | 显示全部楼层

Re:C++基本功和 Design Pattern系列(1) - Inheritance VS Delegation

恩。从基础开始。我也有志于在此发展。多多学习哈!

29

主题

405

帖子

405

积分

中级会员

Rank: 3Rank: 3

积分
405
发表于 2006-10-27 15:04:00 | 显示全部楼层

Re:C++基本功和 Design Pattern系列(1) - Inheritance VS Delegation

我感觉我的基础已经很不错了,为什么学个DX花了半年时间才熟练上手,离精通还差远了.
是不是我IQ有问题啊???

187

主题

6490

帖子

6491

积分

论坛元老

团长

Rank: 8Rank: 8

积分
6491
发表于 2006-10-27 17:25:00 | 显示全部楼层

Re:C++基本功和 Design Pattern系列(1) - Inheritance VS Delegation

你的IQ肯定没有问题。

我学了那么久的C了,看C++的还是很糊涂。

34

主题

443

帖子

478

积分

中级会员

Rank: 3Rank: 3

积分
478
发表于 2006-10-28 12:26:00 | 显示全部楼层

Re:C++基本功和 Design Pattern系列(1) - Inheritance VS Delegation

aear,我爱死你了!
可是怎么不多写一点那啊?
系列(2)呢?

35

主题

370

帖子

376

积分

中级会员

Rank: 3Rank: 3

积分
376
发表于 2006-11-4 20:45:00 | 显示全部楼层

Re:C++基本功和 Design Pattern系列(1) - Inheritance VS Delegation

想必楼主现在DX很牛了?
DX不光是API,里面有很多技巧的。
而且开始单单学你说的那些东西是很枯燥的,结合DX什么的边学边用才好

0

主题

1

帖子

7

积分

新手上路

Rank: 1

积分
7
发表于 2007-1-4 02:21:00 | 显示全部楼层

Re:C++基本功和 Design Pattern系列(1) - Inheritance VS Delegation

这样真好!

6

主题

99

帖子

99

积分

注册会员

Rank: 2

积分
99
发表于 2007-3-29 23:24:00 | 显示全部楼层

Re:C++基本功和 Design Pattern系列(1) - Inheritance VS Delegation

楼主辛苦了,致敬!!!!
我也想向此方面发展,看来还是认真扎实功底才行。
努力!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-6-9 14:15

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表