4_类
类与对象
面向对象的特点:抽象,封装,继承,多态
基本概念
类的成员
- 公有成员:public,与外部的接口,外部函数可以访问公有型数据和函数
- 私有成员:private,只允许本类中的函数访问,类外不可访问;默认为private
- 保护成员:protected,只在继承时与私有成员不同
class Clock{
public:
void setTime(int newH, int newM, int newS);
void showTime();
private:
int hour, minute, second;
protected:
int p;
};
void Clock::setTime(int newH, int newM, int newS){
hour = newH;
minute = newM;
second = newS;
}
void Clock::showTime(){
cout<<hour<<":"<<minute<<":"<<second<<endl;
}
int main(){
Clock myClock;
myClock.setTime(8, 30, 20);
myClock.showTime();
return 0;
}
构造函数
在对象被创建时初始化对象,函数名与类型相同,无返回值无return;构造函数默认调用
-
当未定义构造函数时,编译器自动生成默认构造函数
-
当自定义一个构造函数时,经验上一般后面加上默认构造函数,如下所示
-
委托构造函数:借助一个构造函数构造多个重载的构造函数
-
复制构造函数:用已经存在的新对象初始化新对象,其形参为本类对象的引用
- 用已存在的对象初始化新对象
- 对象作为函数的实参,需要调用复制构造函数初始化形参
- 函数返回值是对象,返回时用复制构造函数初始化无名对象进行返回
析构函数
在对象被删除前的一些清理工作
- 当未定义析构函数时,编译器自动生成默认析构函数(空的)
- 析构函数没有参数表,无return,前面有~
class Clock{
public:
void setTime(int newH, int newM, int newS);
void showTime();
Clock(int newH, int newM, int newS); //自定义构造函数
Clock(); //默认构造函数
Clock(const Clock& p); //复制构造函数
~Clock(); //析构函数
private:
int hour, minute, second;
protected:
int p;
};
void Clock::setTime(int newH=0, int newM=0, int newS=0){
hour = newH;
minute = newM;
second = newS;
}
void Clock::showTime(){
cout<<hour<<":"<<minute<<":"<<second<<endl;
}
Clock::Clock(int newH, int newM, int newS){
hour = newH;
minute = newM;
second = newS;
}
Clock::Clock(){
hour = 0;
minute = 0;
second = 0;
}
Clock::Clock(const Clock& p){
hour = p.hour;
minute = p.minute;
second = p.second;
cout<<"copy construvtor"<<endl;
}
Clock::~Clock(){
cout<<"desconstruct"<<endl;
}
int main(){
Clock a(1, 1, 1);
Clock b(a);
b.showTime();
return 0;
}
类的组合
类的成员为类的对象
- 构造函数:不仅要初始化本类成员,还要初始化对象成员;初始化次序按照成员定义的顺序进行初始化
- 组合类在构造函数中建议使用初始化列表,直接复制没有调用构造函数的
class Point{
private:
int x, y;
public:
Point(int xx=0, int yy=0);
Point(const Point& p);
int getX(){
return x;
}
int getY(){
return y;
}
};
Point::Point(int xx, int yy){
x = xx;
y = yy;
}
Point::Point(const Point& p){
x = p.x;
y = p.y;
cout<<"calling the copy constructor of Point"<<endl;
}
class Line{
public:
Line(Point xp1, Point xp2);
Line(const Line& l);
double getLen(){
return len;
}
private:
Point p1, p2;
double len;
};
Line::Line(Point xp1, Point xp2):p1(xp1), p2(xp2){
cout<<"calling the constructor of Line"<<endl;
double x = static_cast<double>(p1.getX() - p1.getX());
double y = static_cast<double>(p1.getY() - p2.getY());
len = sqrt(x*x + y*y);
}
Line::Line(const Line& l):p1(l.p1), p2(l.p2){
cout<<"calling the copy costructor of Line"<<endl;
len = l.len;
}
int main(){
Point p1(1, 1), p2(4, 5);
Line l1(p1, p2);
Line l2(l1);
cout<<l1.getLen()<<endl;
cout<<l2.getLen()<<endl;
return 0;
}
结构体
特殊形态的类,与类的唯一区别是成员变量默认为公有变量
- 可以使用 { } 进行初始化
struct Point{
int x; //默认为public
int y;
};
int main(){
Point p = {10, 20};
return 0;
}
联合体
所有成员变量公用存储空间,同一时间只有一个成员变量有效
union Mark { //表示成绩的联合体
char grade; //等级制的成绩
bool pass; //只记是否通过课程的成绩
int percent; //百分制的成绩
};
//特殊用法,不需要联合体名称
union {
int i;
float f;
}
//在程序中可以这样使用:
i = 10;
f = 2.2;
枚举类
enum rank {P1=1, P2, P3}; //C语言中的枚举,只能是int类型
enum class 枚举类型名:底层类型{枚举值列表}
enum class Type{General, Light, Medium, Heavy}; //默认为int
enum class Type:char{General, Light, Medium, Heavy};
enum class Category{General=1, Light, Medium, Heavy};
- 强作用域 Type::General
- 转换限制:不可以与整型隐式的相互转换
- 可以指定底层类型