面向对象的程序设计
一、定义类
1.抽象:数据抽象、行为抽象
2.封装:将抽象出的数据成员,行为成员结合,将他们视为整体--类
3.继承与派生:保持原有类特性的基础上,进行更具体的说明
类:用户自定义的数据类型,需要先定义类,再使用。
class 类名{//类体
成员列表
};
成员既可以包括数据成员: 数据成员类型 数据成员名列表; //数据成员声明,逗号隔开分号结束
成员函数:面向对象的设计将数据隐蔽起来,成员函数作为对外界的接口,通过成员函数访问数据。数据成员是属性,成员函数是方法,通过方法存取属性。
若类中有成员函数,则声明成员函数是必须的,而定义成员函数则是可选的;
第一种:将函数的定义放在类里面;
第二种:
class 类名字 {
返回类型 函数名(类型名 参数名)
};
返回类型 类名::函数名(形式参数列表)
{
函数体
}
:: 表示作用域在类里面
类的定义一般放在程序文件开头或者放在头文件中;
也可以放到函数内部或者局部作用域中,若类已经在全局中定义过,则全局定义的类无效,以局部域为主。
在局部作用域中声明的类,其中的函数必须以定义的形式存在,不能以声明存在。
类定义在生命的时候不会产生该成员的实体,不占用存储空间。
二、类成员的访问控制
访问源:1.类成员 2.类用户 类内部成员的调用是类成员,类之外的叫做类用户。
每个成员都具有访问属性:public(共有的) private(私有的) protected(保护的)
公有成员用public表示:类成员和类用户都可以访问之,其实现了类的外部接口
私有成员用priva标号声明,只有类的成员可以访问私有成员,类的用户不被允许,实现了私有成员的隐蔽。
保护成员用protected 声明,若不考虑继承,其性质与私有成员一致,但是保护成员可以被派生的类的成员访问。
class 类名{
public:
成员列表
protected:
成员列表
private:
成员列表
};
若不声明,默认之为私有的。三者次序和数量都是任意的,组合也是任意的,为了清晰,一般按照上面的顺序安排。
三、类的数据成员
类似于普通变量的声明:
class Cube{
long color;
double x,y,z,w;
int a[10];
char *s;
};
类的数据成员还可以是成员对象:包含类类型和结构体类型:下面的类中嵌入了上面的类的对象,称这个对象为子对象。
类Line中嵌入了类Point的子对象start 、end
class Point { //Point类表示点
public:
void set(int a,int b);
int x,y;
};
class Line { //Line类表示线
public:
void set(Point a,Point b);
Point start, end; //成员对象
};
1.除了定义数据成员和成员函数之外,还可以定义自己的局部类型,并且使用类型别名简化,
但是这些定义和声明的数据类型的作用域是类的内部,不能在类外使用。
可以定义结构体/共用体类型,嵌套的类定义、声明枚举类型等。
class ADT { //类定义
struct Point { int x,y; }; //定义结构体
union UData {Point p; long color; }; //定义共用体
enum COLORS {RED,GREEN,BLUE,BLACK,WHITE }; //定义枚举类型
class Nested { //嵌套类定义
… //成员函数
Point start; //数据成员
UData end; //数据成员
COLORS color; //数据成员
};
typedef Point* LPPOINT; //声明类型别名
… //成员函数
… //数据成员
}; //类定义结束
这些结构体、共用体、类型别名等,只能在类内部使用。
在类外部定义函数的时候,需要使用::
返回类型 类名::函数名(形式参数列表)
{
函数体
}
:: 表示作用域在类里面
类内部的函数和类外部定义的函数不冲突,可以同时使用。
::是作用域限定符(fielf qualifed)
如果在作用域限定符前面没有类的名字,或者函数前面既没有类名字也没有作用域限定符号,说明其不属于任何类,是全局的普通函数,这时候这符号没有类作用域限定符的含义,是命名空间域限定符的含义,和不加是一样的。
类的成员函数的原型声明必须要在成员函数的定义之前,因此若不在类内定义函数,则应该先定义类,之后再定义函数。
在类内部声明,外部定义函数,可以减少类的长度,实现类的接口和实现的分离。
四、内联的成员函数
内联函数,将函数代码直接嵌入到相关的地方,不用额外调用。
用inline在函数和声明为内联函数
1.符合内联函数的要求,函数体要简单,不能有循环和Switch语句等
2.符合1,同时在类体内定义的时候,自动的成为内联函数。
3.符合1,同时在类体内显式的指明inline,或在类体外显式指明inline,则函数是内联的。
4.在类外部定义,两侧没有指明inline的时候,函数不是内联的。
效率高,节省了调用和返回的时候的开销。
五、函数的重载
函数的重载指的是定义多个名字相同的函数,同时参数类型或者参数个数需要不同,调用的时候会去对照,找到符合规范的函数调用,二者不冲突,减少了麻烦。
声明成员函数的多个重载版本或者指定其参数的默认值的时候,只能在类的内部进行。必须在函数第一次出现声明或者定义的时候就要指定是否具有函数重载和默认参数。
六、成员函数的存储方式
用类实例化一个对象的时候,系统会为其中的每个对象分配存储空间,C++会为每个成员分配各自独立的存储空间,类似于结构体成员一样。
成员函数的代码有公用的一段存储空间,类里面的成员函数们公用一个空间,但其中不同对象的成员数据占着独自的空间。
因此,一个类的size只与其数据占用的空间大小有关,与函数无关。
一个类只能定义一次,一般给头文件中。
可以只声明不定义,晚些定义也可以。此时只能定义指针和引用,或者作为参数的类型。未定义之前不能去声明变量。
类的成员不能是自己的类,但是可以是指向自己类的指针或者引用。