《通过游戏编程实战 教新手学C++编程》

第1章 类型、变量与标准I/O

控制台窗口停留,批处理文件(.bat):

xxx.exe
pause

命名空间:

using namespace std;

using std::cout;

short int可以缩写成short,long int可以缩写成long。

第2章 真值、分支与游戏循环

任何非零值都解释成true,而0则解释成false。

switch语句只能用来比较int型(或其他可以当做int型处理的值,如char型或枚举数)。

随机数的生成:

#include <cstdlib>
#include <ctime>
srand(static_cast<unsigned int>(time(0))); //基于当前日期与时间为随机数生成器确定种子。
int randomNumber = rand();

第3章 for循环、字符串与数组

string对象包含成员函数length()和size(),都是返回string对象中字符的个数。

#include <string>
if (str.find("hello" == string::npos)) //要搜索的字符串在调用字符串中在存在。
str.erase(4, 5); //移除从位置4开始的长度为5个字符的子字符串。
str.erase(4); //移除从位置4开始之后的字符。
str.erase(); //移除所有字符。

可以在枚举类型中最后添加一个枚举数,用来存储元素的个数:

enum difficulty {EASY, MEDIUM, HARD, NUM_DIFF_LEVELS};

第4章 标准模型库

向量:

#include <vector>
vector<string> vect;
vect.push_back("one");
vect.pop_back();
vect.clear();
vect.insert(vect.begin(), "two");

迭代器:

vector<string>::iterator it;

vector<string>::const_iterator it;
for (it = vect.begin(); it != vect.end(); ++it) //end()返回的迭代器指向向量中最后一个元素之后。
cout << (*it).size(); // it->size()

查找:

#include <algorithm>
it = find(vect.begin(), vect.end(), item);
if (it != vect.end())

乱序:

srand(static_cast<unsigned int>(time(0)));
random_shuffle(vect.begin(), vect.end());

排序(升序):

sort(vect.begin(), vect.end());

统计:

count(vect.begin(), vect.end(), EMPTY)
vect.capacity() //返回向量的容量。
vect.reserve(); //将向量的容量扩充至给定实参的大小。

其他STL容器:
顺序型:
deque:双向队列
list:线性链表
vector:动态数组
关联型:
map:键/值对的集合,每个键都与唯一值关联
multimap:键/值对的集合,每个键可能与多个值关联
multiset:元素不一定唯一的集合
set:元素唯一的集合
适配器:
priority_queue:优先级队列
queue:队列
stack:栈

#include <cctype>
newStr = toupper(str);

第5章 函数

int func(int num); // int func(int);
int func(int num) { return 0; }
int askNumber(int high, int low = 1);
int askNumber(int high, int low) {} //不必在函数定义中重复默认参数。
int triple(int number);
string triple(string text); //创建重载函数,只需要用相同的函数名称和不同的形参列表编写多个函数定义。(与返回值无关)
int radiation(int health); //在函数中不使用inline
inline int radiation(int health) {} //非常小的函数(如只有一两行的函数)


内联函数的定义必须出现在第一次被调用之前。编译器最终决定是否将该函数内联。

第6章 引用

引用为变量提供另一个名称。

int& rScore = score; //声明时必须初始化

引用总是指向其初始化时所用的变量。不可以将引用重新赋值用于引用其他变量。

void swap(int& x, int&y);
swap(one, two);
string& refToElement(const vector<string>& vect, int i)
string& rStr = refToElement(vect, 1);
string str = refToElement(vect, 1);

第7章 指针

指针是一个包含内存地址的变量。

int* pScore = NULL;
pScore = &score;
int* const pScore = &score; //常量指针,无法修改存储在常量指针中的地址。同引用。
const int* pScore; //指向常量的指针,无法修改其指向的值。
const int* const pScore = &score; //指向常量的常量指针。

尽可能地使用引用。引用在语法上比指针更简洁,并且让代码更易读懂。

void swap(int* const pX, int* const pY);
swap(&one, &two);
string* ptrToElement(vector<string>* const pVect, int i)

数组名是指向数组第一个元素的常量指针。

第8章 类

class Critter {
public:
Critter(int hunger = 0);
int GetHunger() const; //常量成员函数,不能修改类中定义的非静态数据成员的值,也不能调用该类的非常量成员函数。
void SetHunger(int hunger);

static int s_Total;
static int GetTotal();
private:
int m_Hunger;
}
int Critter::s_Total = 0;
Critter::Critter(int hunger):
m_Hunger(hunger) //对数据成员快速赋值
{}
Critter::~Critter() {}

第9章 高级类与动态内存

友元函数:

friend void Peek(const Critter& aCritter); //类的友元函数可以访问其任何成员。
Peek(crit);

运算符重载:

ostream& operator<<(ostream& os, const Critter& aCritter) //为内置运算符定义新的意义。

动态分配内存:

int* pHeap = new int(10);
delete pHeap; //释放内存
pHeap = NULL; //处理野指针

如果类在堆中分配内存,则应当编写函数来清理与释放堆中的内存。

浅拷贝:副本对象的指针数据成员与原始对象的指针数据成员指向同一内存块。

拷贝构造函数:

Critter(const Critter& c);
Critter::Critter(const Critter& c) {}

重载赋值运算符:

Critter& Critter::operator=(const Critter& c);
Critter& Critter::operator=(const Critter& c) {}

当类的数据成员指向堆中内存时,应当考虑编写拷贝构造函数来为新对象分配内存,实现深拷贝。应当考虑为该类重载赋值运算符。

第10章 继承与多态

class Boss : public Enemy

基类的一些成员函数并没有被派生类继承。它们是:构造函数、拷贝构造函数、析构函数、重载的赋值运算符。在派生类中必须自己编写这些函数。

为派生类对象调用基类的析构函数保证了每个类都有机会清除其需要处理的对象部分,例如堆中内存。

成员访问权:
public:成员可以被程序中的所有代码访问。
protected:成员只能被本类与特定派生类访问,这取决于继承的访问级别。
private:成员只能被本类访问,即它们不能被任何派生类直接访问。

继承访问权:
public:基类中的成员访问权在派生类中不变。
protected:
private:

调用基类构造函数:

Boss::Boss(int damage):
Enemy(damage)
{}

对于任何继承的基类成员函数,如果期望在派生类中对其重写,则应当使用关键字virtual将其声明为虚函数。
尽管可以重写非虚成员函数,但一个较好的的准则是将任何要重写的基类成员函数声明为虚函数。
在成员函数定义中不使用virtual关键字,只在其声明中使用。
一旦成员函数被声明为虚函数,它在任何派生类中都是虚函数。

多态:

Enemy* pBadGuy = new Boss();

虚函数通过引用和指针来产生多态行为。
虚函数带来的好处不是无条件的,它会降低性能。因此,应当只在需要的时候使用虚函数。
一个很好的经验准则是,如果类中有虚成员函数,则也应当将析构函数声明为虚函数。

抽象类:用来作为其他类的基类,但不用来实例化对象。
当类包含至少一个纯虚函数时,该类为抽象类。

纯虚函数:不需要定义的函数。

virtual void Greet() const = 0;
posted @ 2013-01-18 21:18  joojoosue  阅读(479)  评论(1编辑  收藏  举报