目录
面向过程和面向对象初步认识
类的引入
类的定义
类的两种定义方式:
1. 声明和定义全部放在类体中
2. 类声明放在.h文件中,成员函数定义放在.cpp文件中
类的访问限定符及封装
1 访问限定符
2 封装
类的实例化
类对象的存储方式
this指针
面向过程和面向对象初步认识
C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题
比如炒菜(注重过程):准备蔬菜->清洗切刀->下锅烹煮->碟碗盛放
C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完
成
再比如空气炸锅来完成食物,(注重对象):人、食物、空气炸锅
人只需要将食物送进空气炸锅,等待食物可食用即可,我们不需要关心空气炸锅怎么将食物做好
整个过程是由人、空气炸锅、食物三个对象之间的交互完成的
类的引入
C语言结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数
以栈的实现为例,具体实现我就不写了,只构造大概框架
以下结构体的定义,在C++中更喜欢用class来代替
struct Stack
{
//成员函数
void Init()
{
a = nullptr;
top = capacity = 0;
}
void Push(int x)
{
//……
}
//成员变量
int* a;
int top;
int capacity;
};
int main()
{
Stack st;
st.Init();//访问更便利
st.Push(1);
st.Push(2);
return 0;
}
类的定义
class className//类名
{
// 类体:由成员函数和成员变量组成
}; // 一定要注意后面的分号
类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者成员函数
类的两种定义方式:
1. 声明和定义全部放在类体中
注意:成员函数如果在类中定义,编译器可能会将其当成内联函数处理
以栈为例:
class Stack
{
public:
void Init()
{
a = nullptr;
top = capacity = 0;
}
void Push(int x)
{
//……
}
private:
int* a;
int top;
int capacity;
};
2. 类声明放在.h文件中,成员函数定义放在.cpp文件中
更推荐这种
注意:成员函数名前需要加类名::
因为类定义了一个新的作用域,需要使用 ::作用域操作符指明成员属于哪个类域
//Stack.h
class Stack
{
public:
void Init();
void Push(int x);
private:
int* a;
int top;
int capacity;
};
//Stack.cpp
#include"Stack.h"
void Stack::Init()
{
a = nullptr;
top = capacity = 0;
}
void Stack:: Push(int x)
{
//……
}
类的访问限定符及封装
1 访问限定符
C++实现封装的方式:用类将对象的属性与方法结合在一块,让对象更加完善,通过访问权限选
择性的将其接口提供给外部的用户使用
1 public修饰的成员在类外可以直接被访问
2 protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)
访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止/后面没有访问限定符,作用域就到 } 即类结束
3 class的默认访问权限为private,struct为public
2 封装
封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来
和对象进行交互,也就是通过访问权限来隐藏对象内部实现细节,控制哪些方法可以在类外部直接被使用
类的实例化
用类类型创建对象的过程,称为类的实例化
类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没
有分配实际的内存空间来存储它
实例化出的对象 占用实际的物理空间,存储类成员变量
形象点来说,类就像房子的设计图纸,设计出需要什么,而实例化出的对象就是实体的房子
class Stack
{
public:
void Init()
{
a = nullptr;
top = capacity = 0;
}
void Push(int x)
{
//……
}
private:
int* a;
int top;
int capacity;
};
int main()
{
Stack st;//实例化
return 0;
}
类对象的存储方式
每个对象中只保存成员变量,成员函数存放在公共代码区
this指针
我们先看一段日期类Date的代码:
class Date
{
public:
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << "/" << _month << "/" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
Date d2;
d1.Init(2023,7,22);
d2.Init(2023, 7, 23);
d1.Print();
d2.Print();
return 0;
}
在调用Init函数和Print函数时,它们是怎么精准区分不同对象的呢?知道该为哪个对象进行操作呢?
C++中通过引入this指针解决该问题:C++编译器给每个“非静态的成员函数“增加了一个隐藏
的指针参数,即this指针(调用函数的对象的地址,指向该对象),让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量”的操作,都是通过该指针去访问
this指针的特性
1. this指针的类型:类类型* const,即成员函数中,不能给this指针赋值(不可对this指针本身进行修改)。
2. 只能在“成员函数”的内部使用
3. this指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给
this形参。所以对象中不存储this指针。
4. this指针是“成员函数”第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传
递,不需要用户传递
其实this指针作为函数的形参是不可用显示化的,但是可以在成员函数内部显示的使用,同时要注意不能对this指针本身进行修改