什么是面向过程和面向对象?
C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。
C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。
1.类的引入
C++的类,类似于C语言的结构体;
C语言的结构体中只能定义变量,C++的struct中也可以定义函数。
//C++兼容C结构体用法
typedef struct ListNode{
int val;
struct ListNode* next;
}LTN;
//C struct ListNode是类型
//C++把结构体升级成了类
struct ListNode {
int val;
ListNode* next;
};
以上是结构体定义,在C++中喜欢用class来代替。
2.Class类的定义
class className
{
// 类体--> 成员函数 / 成员变量
}; // 一定要注意后面的分号
Class:定义类的关键字
ClassName:类的名字
类体:类的成员,包括类中的变量(称作类的属性或成员变量)和 类中的函数(称作类的方法或成员函数)
类的示例:
class Date
{
public:
void Init(int year) {
_year = year;//赋值时(初始化)便于区分
}
private:
int _year;//成员变量常加一个"_"//
};
类的两种定义方式:
1.声明和定义全都放在类体中:
class Person
{
public:
void showInfo() {
cout << _name << "-" << _sex << "-" << _age << endl;
}
private:
char* _name;
char* _sex;
int _age;
};
2.声明和定义分离:
类声明放在.h文件中,成员函数定义放在.cpp文件中
注意:成员函数前需要加类名( person:: )
//person.h
class person
{
public:
void showInfo();
public:
char* _name;
char* _sex;
int _age;
};
//person.cpp
void person::showInfo() {
cout << _name << "-" << _sex << "-" << _age << endl;
}
3.类的访问限定符
public:公有
protected:保护
private:私有
【访问限定符说明】
- public修饰的成员在类外可以直接被访问
- protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)
- 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止
- 如果后面没有访问限定符,作用域就到 } 即类结束。
- class的默认访问权限为private,struct为public(因为struct要兼容C)
- 成员变量常私有,成员函数常公有。
【总结】C++中struct和class的区别是什么?
C++需要兼容C语言,所以C++中struct可以当成结构体使用。另外C++中struct还可以用来定义类。和class定义类是一样的,区别是struct定义的类默认访问权限是public,class定义的类默认访问权限是private。注意:在继承和模板参数列表位置,struct和class也有区别,后序给大家介绍。
4.类的作用域
类定义了一个新的作用域,在类体外定义成员时,需要使用::作用域操作符指明成员属于哪个类域。
class Person
{
public:
void PersonInfo();
private:
char _name[20];
char _gender[3];
int _age;
};
// 这里需要指定PersonInfo是属于Person这个类域
void Person::PersonInfo()
{
cout << _name << " "<< _gender << " " << _age << endl;
}
5.类的实例化
用类类型创建对象的过程,称为类的实例化。
- 类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没
有分配实际的内存空间来存储它 - 一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量
class Date
{
public:
void Init(int year, int month, int day) {
_year = year;
_month = month;
_day = day;
}
private:
int _year; //声明
int _month;
int _day;
};
int mian() {
//类对象实例化 -- 开空间
Date d1;
Date d2;
d1.Init(2023, 2, 2);
d2.Init(2024, 3, 2);
}
注意:建立的对象d1,d2的空间中不包含Init函数;因为每个对象的成员变量不同,要独立存储,但每个对象的成员函数一样,这些函数存储在公共代码段。
6.this指针
Init初始化调用后,数据没有存在_year中,也没有存在d1中?
原来,在成员函数中,编译器会自动加一个this指针,但是被隐藏掉了。
在编译器的视角中,会多一个隐藏的参数:
//编译器视角
class Date
{
public:
void Init(Date* this, int year, int month, int day) {
this->_year = year;
this->_month = month;
this->_day = day;
}
private:
int _year;
int _month;
int _day;
};
int mian() {
Date d1;
d1.Init(&d1, 2023, 2, 2);
}
注意1:在实参和形参的地方不可以显示的加this,但是在类里可以显示的使用(如运算符重载)
注意2:this指向当前对象,我们可以通过在Init里打印this发现打印出来d1的地址。
注意3:this指针作为隐含形参,存在栈上。