类声明中的内容包括数据和函数,分别称为数据成员和成员函数。按访问权限划分,数据成员和成员函数又可分为共有、保护和私有3种
class 类名{
public:
公有数据成员;
公有成员函数;
protected:
保护数据成员;
保护成员函数;
private:
私有数据成员;
私有成员函数;
};
这个类和C语言中的结构体很像,这个像不是它里面的数据,而是用法,比如class Area {.......} area1,area2;Area area ;Area *area;
类声明中的关键字private、protected、public可以任意顺序出现。若私有部分处于类的第一部分时,关键字private可以省略。这样,如果一个类体中没有一个访问权限关键字,则其中的数据成员和成员函数都默认为私有的。不能在类声明中给数据成员赋初值。 成员函数 普通成员函数的定义
在类的声明中只给出成员函数的原型,而成员函数的定义写在类的外部。这种成员函数在类外定义的一般形式是:
返回值类型 类名::成员函数名(参数表){函数体}
#include内联函数的定义using namespace std; class Area { public : int ShowArea(); void SetLongWide (int x, int y); private: int lenth; int wide; }; void Area::SetLongWide(int x, int y) { lenth = x; wide = y; } int Area::ShowArea() { return lenth * wide; } int main() { int i = 0; Area area; area.SetLongWide(3,4); i = area.ShowArea(); cout << "面积:" << i << endl; return 0; }
在函数名前冠以关键字inline,该函数就被声明为内联函数。每当程序中出现对该函数的调用时,C++编译器使用函数体中的代码插入到调用该函数的语句之处,同时使用实参代替形参,以便在程序运行时不再进行函数调用。引入内联函数主要是为了消除调用函数时的系统开销,以提高运行速度。
内联函数在第一次被调用之前必须进行完整的定义,否则编译器将无法知道应该插入什么代码在内联函数体内一般不能含有复杂的控制语句,如for语句和switch语句等使用内联函数是一种空间换时间的措施,若内联函数较长,较复杂且调用较为频繁时不建议使用
隐式声明:将成员函数直接定义在类的内部
#includeusing namespace std; class Area { public : int ShowArea() { return lenth * wide; } void SetLongWide (int x, int y) { lenth = x; wide = y; } private: int lenth; int wide; }; int main() { int i = 0; Area area; area.SetLongWide(3,4); i = area.ShowArea(); cout << "面积:" << i << endl; return 0; }
显式声明:在类声明中只给出成员函数的原型,而将成员函数的定义放在类的外部。
#includeusing namespace std; class Area { public : int ShowArea(); void SetLongWide (int x, int y); private: int lenth; int wide; }; inline void Area::SetLongWide(int x, int y) { lenth = x; wide = y; } inline int Area::ShowArea() { return lenth * wide; } int main() { int i = 0; Area area; area.SetLongWide(3,4); i = area.ShowArea(); cout << "面积:" << i << endl; return 0; }
在类中,使用inline定义内联函数时,必须将类的声明和内联成员函数的定义都放在同一个文件(或同一个头文件)中,否则编译时无法进行代码置换。
构造函数构造函数是一种特殊的成员函数,它主要用于为对象分配空间,进行初始化。构造函数的名字必须与类名相同,而不能由用户任意命名。它可以有任意类型的参数,但不能具有返回值。它不需要用户来调用,而是在建立对象时自动执行。
#includeusing namespace std; class Area { public: Area(int m, int f); int ShowArea(); void SetLongWide(int x, int y); private: int lenth; int wide; }; Area::Area(int m, int f) { lenth = m; wide = f; } //或者如下: //Area::Area(int m, int f):lenth(m), wide(f) { // cout << "构造函数使用中..." << endl; //} void Area::SetLongWide(int x, int y) { lenth = x; wide = y; } int Area::ShowArea() { return lenth * wide; } int main() { int i = 0; Area area(1,2); area.SetLongWide(3, 4); i = area.ShowArea(); cout << "面积:" << i << endl; return 0; }
或者采用如下的方式:
#includeusing namespace std; class Area { public: Area(int m, int f) :lenth(m), wide(f) {} int ShowArea(); void SetLongWide(int x, int y); private: int lenth; int wide; }; void Area::SetLongWide(int x, int y) { lenth = x; wide = y; } int Area::ShowArea() { return lenth * wide; } int main() { int i = 0; Area area(1,2); //area.SetLongWide(3, 4); i = area.ShowArea(); cout << "面积:" << i << endl; return 0; }
构造函数的名字必须与类名相同,否则编译程序将把它当做一般的成员函数来处理。构造函数没有返回值,在定义构造函数时,是不能说明它的类型的。与普通的成员函数一样,构造函数的函数体可以写在类体内,也可写在类体外。构造函数一般声明为共有成员,但它不需要也不能像其他成员函数那样被显式地调用,它是在定义对象的同时被自动调用,而且只执行一次。构造函数可以不带参数。 析构函数
析构函数也是一种特殊的成员函数。它执行与构造函数相反的操作,通常用于撤销对象时的一些清理任务,如释放分配给对象的内存空间等。析构函数有以下一些特点:
析构函数与构造函数名字相同,但它前面必须加一个波浪号(~)。
析构函数没有参数和返回值,也不能被重载,因此只有一个。
当撤销对象时,编译系统会自动调用析构函数。
如果没有给类定义构造函数和析构函数,则编译系统自动生成一个默认的构造函数和析构函数。
带有默认参数值的函数当进行函数调用时,编译器按从左到右的顺序将实参与形参结合,若未指定足够的实参,则编译器按顺序用函数原型中的默认值来补足所缺少的实参。在函数原型中,所有取默认值的参数都必须出现在不取默认值的参数的右边。
int fun(int a, int b, int c = 111);
在函数调用时,若某个参数省略,则其后的参数皆应省略而采取默认值。不允许某个参数省略后,再给其后的参数指定参数值。
函数重载在C++中,用户可以重载函数。这意味着,在同一作用域内,只要函数参数的类型不同,或者参数的个数不同,或者二者兼而有之,两个或者两个以上的函数可以使用相同的函数名。
调用重载函数时,函数返回值类型不在参数匹配检查之列。因此,若两个函数的参数个数和类型都相同,而只有返回值类型不同,则不允许重载。
int mul(int x, int y); double mul(int x, int y);
函数的重载与带默认值的函数一起使用时,有可能引起二义性。
void Drawcircle(int r = 0, int x = 0, int y = 0); void Drawcircle(int r); Drawcircle(20);
在调用函数时,如果给出的实参和形参类型不相符,C++的编译器会自动地做类型转换工作。如果转换成功,则程序继续执行,在这种情况下,有可能产生不可识别的错误。
void f_a(int x); void f_a(long x); f_a(20.83);其他基础知识 作用标识符‘: :’
如果希望在局部变量的作用域内使用同名的全局变量,可以在该变量前加上“: :”,此时: :value代表全局变量value,
new和delete运算符C语言中使用函数malloc()和free()来进行动态内存管理。C++则提供了运算符new和delete来做同样的工作,而且后者比前者性能更优越,使用更灵活方便。
指针变量名 = new 类型 int *p; p = new int; delete 指针变量名 delete p;
下面对new和delete的使用再做一下几点说明:
用运算符new分配的空间,使用结束后应该用也只能用delete显式地释放,否则这部分空间将不能回收而变成死空间。
在使用运算符new动态分配内存时,如果没有足够的内存满足分配要求,new将返回空指针(NULL)。
使用运算符new可以为数组动态分配内存空间,这时需要在类型后面加上数组大小。
指针变量名 = new 类型名[下标表达式]; int *p = new int[10];
释放动态分配的数组存储区时,可使用delete运算符。
delete []指针变量名; delete p;
new 可在为简单变量分配空间的同时,进行初始化
指针变量名 = new 类型名(初值); int *p; p = new int(99); ··· delete p;引用(reference)
引用是C++对C的一个重要扩充。变量的引用就是变量的别名,因此引用又称别名。
类型 &引用名 = 已定义的变量名
引用与其所代表的变量共享同一内存单元,系统并不为引用另外分配存储空间。实际上,编译系统使引用和其代表的变量具有相同的地址。
不允许建立void类型的引用不能建立引用的数组不能建立引用的引用。不能建立指向引用的指针。引用本身不是一种数据类型,所以没有引用的引用,也没有引用的指针。可以将引用的地址赋值给一个指针,此时指针指向的是原来的变量。可以用const对引用加以限定,不允许改变该引用的值,但是它不阻止引用所代表的变量的值。



