11类与对象
类(class)——是抽象数据类型,实现了对数据和函数的封装(必须通过接口函数才能操作数据)
数据成员
1.可以定义各种类型的变量、指针、数组等,甚至是其他类的对象
2.在类的定义中数据成员不能赋初值
3.数据成员一般放在private部分
4.数据成员也可以放在public部分,但不提倡
成员函数
1.可以放在public部分(可以被外部函数调用),也可以是私有的(供自己的成员函数使用)
2.成员函数的实现一般放在类定义的外面(也可以在类的里面),并且与类的定义不在一个文件中
访问控制
1.三个访问说明符:public、private和protected。作用——控制对类的成员的访问
2.在用class定义的类中,默认的访问方式是private
3.在类的定义中,三个访问说明符都可以使用多次(不提倡)
访问控制
1.类的私有成员只能被类的成员函数、友元访问
2.类的受保护成员能被类的成员函数、友元和(直接)派生类成员函数、友元访问
3.类的公有成员可以被类的成员函数、友元以及所有能访问到类的对象的外部程序访问
4.类的公有成员是类的对外接口
最低访问权原则
1.如果某函数不需要访问某些数据,则不给它访问的权限(如类的私有属性)
2.如果某函数需要读取某数据的值,但不需要修改它,则只给它读的权限(如函数的const参数)
3.只有当函数需要修改某数据时才给它全部的访问权限
静态成员
1.类的对象独立拥有自己的数据成员空间,共享类的成员函数
2.对象之间相互独立,消息是对象之间交互的唯一方式
3.类的静态成员包括静态数据成员和静态成员函数
4.类的静态数据成员属于类,被类的所有对象共享
5.类的静态成员可以是私有的、公有的或受保护的
6.静态数据成员不依赖于对象而存在
7.静态成员函数是操作静态数据成员的函数
8.静态成员函数只能访问类的静态成员,不能调用非静态成员函数、不能访问非静态数据成员
9.非静态成员函数可以访问静态数据成员,也可以调用静态成员函数
10.访问静态成员的方式:
对象名 + 点操作符
对象的引用 + 点操作符
对象指针 + 箭头操作符
类名 + 作用域运算符(::)
头文件的包含问题
头文件会被其他头文件或源文件包含
一个源文件可能会多次包含一个头文件
b.h 包含 a.h
c.h 包含 a.h
d.cpp 包含 b.h 和 c.h
a.h中的内容被重定义
预处理指令#if !defined和#endif
#if !defined __CIRCLE__H__
判断标识符__CIRCLE__H__是否被定义,如果没有则编译后续程序,否则跳过后续语句直到指令#endif
第一次包含头文件circle.h时,__CIRCLE__H__没被定义,类Circle的定义被编译,__CIRCLE__H__被定义
第二次包含头文件circle.h时,__CIRCLE__H__已经被定义,类Circle的定义被跳过,防止重复定义
示例
//文件circle.h
#if !defined __CIRCLE__H__
#define __CIRCLE__H__
#include <iostream.h>
class Circle
{public:
Circle();
void draw();
private:
double x, y; //x、y坐标
double r; //半径
};
#endif
使用类定义对象
Circle one; //声明类Circle的对象one
Circle array[10]; //声明对象数组array
Circle *ptr = &one; //声明对象指针
Circle &o = one; //声明对象引用
Circle *pone, *pten; //声明两个指针
pone = new Circle;//动态创建一个对象
pten = new Circle[10];//动态创建对象数组
构造函数
1.函数名和类名完全相同
2.没有返回类型
3.在对象建立时被自动调用
4.用于初始化类的对象,保证对象在创建后其数据成员都已经被正确初始化
构造函数执行的时机
1.对象被声明或创建时,构造函数被自动调用
2.全局对象在所有程序执行之前被创建
3.局部自动对象在程序执行到声明该对象的语句时被创建
4.局部静态对象在程序首次执行到声明该对象的语句时被创建
5.动态对象(用new运算符创建)在程序执行到该语句时被创建
构造函数重载
1.类的构造函数可以重载
2.重载的构造函数的函数名完全相同,都没有返回类型,但参数列表各不相同
3.类有多个构造函数时,系统根据创建对象时提供的参数来确定调用哪个构造函数
示例
//文件circle.h
#if !defined __CIRCLE__H__
#define __CIRCLE__H__
#include <iostream.h>
class Circle
{public:
Circle( )
{ x = y = r = 5.0; }
Circle(double a, double b, double c)
{x = a;
y = b;
if (c>0) r = c;
else r = 5.0;
}
void draw()
{cout << "Draw a circle at (“
<< x << ","<<y
<< "), with radius " << r
<< "." << endl;
}
private:
double x, y; //x、y坐标
double r; //半径
};
#endif
解析:
声明类Circle的对象
Circle obj; //不能是Circle obj( );
//调用第1个构造函数,对象obj中的x、y、r都被赋值为5.0
Circle obj1(4.0, 5.0, 6.0);
//调用第2个构造函数,对象obj中的x、y、r分别被赋值为4.0、5.0和6.0
默认构造函数
1.调用时不需要参数的构造函数是默认构造函数,如:类Circle的第一个构造函数是默认构造函数
2.所有参数都是默认参数的构造函数是默认构造函数
3.当一个类没有定义任何构造函数时,系统为该类自动生成默认构造函数 类名(){ }
4.一个类至多拥有一个默认构造函数
示例:
Circle(double a = 5.0, double b = 5.0, double c = 5.0)
复制构造函数(拷贝构造函数)
1.根据类的某个对象复制出一个内容完全相同的新对象的构造函数叫复制构造函数
2.复制构造函数的参数是该类的对象(传引用的方式)
3.如果类定义时没有定义复制构造函数,编译时会自动加入一个完成数据成员复制的复制构造函数
4.当参数传对象值或函数返回对象值时自动调用复制构造函数
示例:
//文件circle.h
#if !defined __CIRCLE__H__
#define __CIRCLE__H__
#include <iostream.h>
class Circle
{public:
//带默认参数的构造函数
Circle(double a = 5.0, double b = 5.0, double c = 5.0)
{ x = a;
y = b;
if (c>0) r = c;
else r = 5.0;
}
//复制构造函数
Circle(Circle &c)
{ x = c.x;
y = c.y;
r = c.r;
}
void draw()
{cout << "Draw a circle at (“
<< x << ","<<y
<< "), with radius " << r
<< "." << endl;
}
private:
double x, y; //x、y坐标
double r; //半径
};
#endif
解析:
使用复制构造函数
Circle a(3.0, 4.0, 5.0);
Circle b(a);
当对象中包含指向动态空间的指针数据成员时,复制构造函数的实现不能只是简单的赋值
应该先为当前对象分配新的空间
再将参数对象中相应的数据复制过来
析构函数
1.析构函数名是字符‘~’加上类名
2.析构函数不能指定返回类型
3.没有参数
4.不能被重载
5.当一个类没有定义任何析构函数时,系统为该类自动生成析构函数 ~类名(){ }
6.其作用是在撤销对象前为对象做最后的清理工作,一般为释放对象在生存期内动态分配的空间
析构函数执行的时机
1.对象被撤销时,类的析构函数被自动调用
2.全局对象在所有程序执行完毕之后被撤销(执行完main函数最后一条语句或执行exit语句之后)
3.如果程序以abort语句终止执行,全局对象的析构函数不被执行
4.局部自动对象在退出该对象的作用域时被撤销
5.如果程序在退出该程序块之前以exit或abort终止执行,局部自动对象的析构函数不会执行
6.局部静态对象在程序执行完毕后或程序执行exit语句之后,其析构函数被执行
7.如果程序以abort语句终止执行,局部静态对象的析构函数不被执行
8.局部静态对象的析构函数在全局对象的析构函数执行之前执行
9.动态创建对象的析构函数在执行相应的delete操作时执行
示例:
//文件createanddestroy.h
#if !defined __CREATEANDDESTORY__H__
#define __CREATEANDDESTORY__H__
#include <iostream.h>
class CreateAndDestroy
{public:
CreateAndDestroy(int n)
{no = n;
cout<<"Object “
<<no<<" created!"<<endl;}
~CreateAndDestroy()
{cout<<"Object “
<<no<<" destructed!"<<endl;}
private:
int no; }; #endif
//文件ex11_6.cpp
#include "createanddestroy.h"
CreateAndDestroy one(1);//定义全局对象one
main()
{CreateAndDestroy *ptr;
CreateAndDestroy two(2);
//定义局部自动对象two
{CreateAndDestroy three(3);
//定义局部自动对象three
ptr = new CreateAndDestroy(4);
//动态创建对象,由ptr指向
static CreateAndDestroy five(5);
//定义局部静态对象five
}
delete ptr; //释放动态创建的对象
return 0;
}