VC++基础学习2
多文件结构
在工程中建立若干用户定义的头文件.h和源程序文件.cpp。
如果源程序文件中有编译预处理指令,则首先经过编译预处理生成临时文件存放在内存,之后对临时文件进行编译生成目标文件.obj,编译后临时文件撤销。所有的目标文件经连接器连接最终生成一个完整的可执行文件.exe。
下图是一个多文件系统的开发过程。
C++编译预处理:宏定义指令、文件包含指令和条件编译指令
宏定义指令
◆ 不带参数的宏定义:用来产生与一个字符串(即宏名)对应的常量字符串,格式为:#define 宏名 常量串
◆ 带参数的宏定义:带参宏定义的形式很象定义一个函数,格式为:
#define 宏名(形参表) 表达式串
- 宏替换只是字符串和标识符之间的简单替换,预处理本身不做任何数据类型和合法性检查,也不分配内存单元。
- 宏定义时,形参通常要用括号括起来,否则容易导致逻辑错误。例如,如果定义:
#define S(a,b) a*b/2 - 则程序中可使用S(a,b),编译预处理后产生中间文件,其中S(a,b)被替换成(a)*(b)/2
条件编译指令
条件编译指令包括:
#if、#else、#ifdef、#ifndef、#endif、#undef等。可分为两类:
- 用宏名作为编译的条件,格式为:
#ifdef<宏名>
<程序段1>
[#else
<程序段2>]
#endif - 用表达式的值作为编译条件,格式为:
#if <表达式>
<程序段1>
[#else
<程序段2>]
#endif
类定义的更关键部分是对数据成员的操作。这可以用函数来完成。这些函数也作为类的成员存在!
class CGoods
{
private :
char Name[21] ;
int Amount ;
float Price ;
float Total_value ;
public :
void RegisterGoods(char*,int,float); //登记新商品,此处是函数头
void CountTotal(void) ; //计算商品总价值
void GetName(char*) ; //读取商品名
int GetAmount(void) ; //读取商品数量
float GetPrice(void) ; //读取商品单价
float GetTotal_value(void) ; //读取商品总价值
}; //注意一定要有;
这个描述商品的方案中,在类中引进了成员函数(或称函数成员)(member function),也就是函数也成了数据(类)中的成员。成员函数可以直接使用类定义中的任一成员,可以处理数据成员,也可调用其他函数成员。
类把数据(事物的属性)和函数(事物的行为——操作)封装为一个整体。
在前面,只对成员函数作了一个声明,或者讲只给出了函数的原型,并没有对函数进行定义。函数定义通常在类的说明之后进行。
商品类CGoods中的成员函数可以如下定义:(在前面的代码后加上以下部分)
void CGoods::RegisterGoods(char* name,int amount, float price)
//登记新商品
{
//char*是指向字符的指针类型说明,name现可理解为字符串
strcpy(Name , name) ; //字符串拷贝函数
Amount=amount ; Price=price ;
}
类是一种数据类型,定义时系统并不为类分配存储空间,类只是一个样板,以此样板可以在内存中开辟出一个个同样结构的实例——对象,系统为对象分配内存。
构造函数的定义与使用
◆ 1、什么是构造函数
构造函数是特殊的public型成员函数,其特征如下:
- 函数名与类名相同。
- 构造函数无函数返回类型说明。注意是没有而不是void,即什么也不写,也不可写void!实际上构造函数有返回值,返回的就是构造函数所创建的对象。
- 在程序运行时,当新的对象被建立,该对象所属的类的构造函数自动被调用,在该对象生存期中也只调用这一次。
- 构造函数可以重载。严格地讲,说明中可以有多个构造函数,它们由不同的参数表区分,系统在自动调用时按一般函数重载的规则选一个执行。
- 构造函数可以在类中定义,也可以在类外定义。
- 如果类说明中没有给出构造函数,则C++编译器自动给出一个缺省的构造函数:类名(void) { }; ,不论自己定义还是C++编译器给出,缺省的构造函数只有一个。
什么是析构函数
当一个对象定义时,C++自动调用构造函数建立该对象并进行初始化,那么当一个对象的生命周期结束时,C++也会自动调用一个函数注销该对象并进行善后工作,这个特殊的成员函数即析构函数(destructor):
- 析构函数名也与类名相同,但在前面加上字符‘~’,如~CGoods()。
- 析构函数无函数返回类型,与构造函数在这方面是一样的。但析构函数不带任何参数。
- 一个类有一个也只有一个析构函数,这与构造函数不同。析构函数也可以缺省。
- 对象注销时,系统自动调用析构函数。
2、析构函数的使用
对象用完后,系统会自动调用的,不用烦了。但是,动态对象要记着自己主动释放!
void CGoods::CountTotal(void) //计算商品总价值
{
Total_value = Price*Amount;
}