高级语言中有面向过程的,比如经典的C语言,有面向对象的,例如:c++,java,那么两种思想有什么不同呢?
面向过程关注的过程,分析出求解问题的步骤,通过函数调用逐步解决问题。面向对象更加关注对象本身,用对象和对象之间的实例化和交互实现功能。
类的概念
c语言中基本内置类型有int、double、char
等等,自定义类型需要struct关键字去定义,但是结构体内只能定义变量,不可以定义函数。而C++中是可以定义函数的,而C++中称自定义类型为类。
//C++的类
struct Stu {
void swap(int& x,int& y) {
int tem = x;
x = y;
y = tem;
}
int a;
int b;
};
C++是兼容C语言的,自定义类型可以用struct,但是C++程序员跟喜欢用class关键字来定义类。
类的定义
- 直接在类里面定义成员函数
//class为关键字,Date为类名
class Date {
//访问修饰限定符 public
public:
//类的成员函数
void show(){
std::cout<<_year<<"年"<<_month<<"月"<<_day<<"日"<<std::endl;
}
void Init(int year, int month, int day) {
//初始化成员变量,形参名字和成员变量要区分开,所以命名成员函数时要区分
_year = year;
_month = month;
_day = day;
}
//访问修饰限定符private
private:
//类的成员变量
int _year;
int _month;
int _day;
};
- 类的成员函数定义在类里面,默认会当成内联函数处理,还有一种定义类的方式:类和成员函数的声明在头文件,成员函数的声明在cpp中。
#pragma once
class Date {
public:
//声明成员函数
void show();
void Init(int year, int month, int day);
private:
int _year;
int _month;
int _day;
};
#include "Date.h"
//定义成员函数要加上 类名::
void Date::show(){
std::cout<<_year<<"年"<<_month<<"月"<<_day<<"日"<<std::endl;
}
void Date::Init(int year, int month, int day) {
//初始化成员变量,形参名字和成员变量要区分开,所以命名成员函数时要区分
_year = year;
_month = month;
_day = day;
}
类的访问限定符及封装
面向对象三个特性,封装,继承,多态。我们这里的访问限定符就是类的封装特性。
访问限定符:public、private、protect。
这三种限定符修饰成员变量和成员函数
- public修饰的成员在类外可以直接被访问
- protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)
- 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止
- 如果后面没有访问限定符,作用域就到 } 即类结束。
- class的默认访问权限为private,struct为public(因为struct要兼容C)
类对象实例化
类只是声明定义并不会开空间,只有在实例化的时候才会开辟空间,例如:
//类的声明定义
class Date {
public:
//声明成员函数
void show();
void Init(int year, int month, int day);
private:
int _year;
int _month;
int _day;
};
int main(){
//类只有定义实例化才会开辟空间
Date d1;
return 0;
}
一个类可以实例化很多个对象,比如:建造楼房时,我们必须先画图画出建筑物的模型图,根据这张图纸可以建造很多楼房。图纸就像是一个类,建造楼房就像是类的实例化。
类的内存结构
-
类在实例化的时候才会向内存申请空间,那么申请多大,换句话说就是类的大小怎么计算。
类的大小就是成员变量加起来的字节大小,但是要和C语言中struct结构体一样考虑内存对齐的问题。如果不太了解的小伙伴参考(链接: link)。 -
但是类中还有成员函数的定义或者声明,他们是怎么存储的呢?
类中的成员函数会存放在一个公共的代码段。一个类可以实例化多个对象,每个对象的成员函数内实现的代码都是一样的,所以没有必要实例化一个对象就为成员函数开辟空间,会造成不必要的消耗,所以类的成员函数会放在公共的代码段区域内。
this指针
class Date {
public:
void show(){
std::cout<<_year<<"年"<<_month<<"月"<<_day<<"日"<<std::endl;
}
void Init(int year, int month, int day) {
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
int main(){
Date d1;
Date d2;
d1.Init(2000,10,03);
d2.Init(2001,09,09);
d1.show();
d2.show();
return 0;
}
我们在main中实例化了两个对象,d1,d2,分别都调用成员函数。那么放在公共代码段内的成员函数怎么知道是谁调用了他们,其实类中有一个隐藏的this指针,是存放当前对象的地址,只不过调用成员函数时候编译器会自动帮我们隐式传递这个指针。
void Init(int year, int month, int day) {
//初始化成员变量,形参名字和成员变量要区分开,所以命名成员函数时要区分
_year = year;
_month = month;
_day = day;
}
//this显示
void Init(Date* this int year, int month, int day) {
//初始化成员变量,形参名字和成员变量要区分开,所以命名成员函数时要区分
this->_year = year;
this->_month = month;
this->_day = day;
}
这两个成员函数是一样的,只不过我平时会写成第一种,第二种是显示this指针的,写成第一种就可以,编译器会帮我们自动写上this指针,不需要我们自己写。