目录
1.类的引入
在C语言中,结构体只能定义变量,而在C++中结构体不仅能够定义变量,也能够定义函数。
struct Date {
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
int _year;
int _month;
int _day;
};
而在C++中,结构体的定义更喜欢用class来定义。
2.类的定义
class classname
{
//类体:有成员函数和成员变量组成;
}; //一定要注意后面的分号
class为定义类的关键字,classname为类的名字,{}中为类的主体,注意类定义结束时的分号。
类中的元素称为类的成员,类中的数据称为类是属性或者成员变量,类中的函数称为类的方法或者成员函数。
类的两种定义方式:
1.声明和定义全部放在类中,需要注意:成员函数如果在类中定义,编译器可能会将其当成内联函数处理。但是到底当不当成内联函数处理是有编译器处理的。
struct Date {
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
int _year;
int _month;
int _day;
};
2.声明放在.h文件中,类的定义放在c.cpp文件中;或者声明和定义都在cpp中,但是不在类中。一般情况下,更期望采用这一种方式。
struct Date {
void Init(int year, int month, int day);
int _year;
int _month;
int _day;
};
//函数定义在类外面
void Date::Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
3.类的访问限定符及封装
3.1访问限定符
C++实现封装的方式,用类将对象的属性与方法结合到一块,让对象更加完善,通过访问权限选择性的将其接口提供给外部的用户使用。
访问限定符说明:
public修饰的成员在类外可以直接访问;
protected和private修饰的成员在类外面不能直接访问;
访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现为止;
class的默认访问权限是private,struct为public(因为要struct要兼容C)
C++中struct和class的区别是什么?
C++要兼容C,所以C++中struct可以当成结构体使用,另外C++中struct还可以用来定义类,和class定义类是一样的,区别是struct的成员默认访问方式式public,class的成员默认访问方式式private。
3.2封装
封装:将数据和操作数的方法进行有机的结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。
面像对象的三大特性:封装、继承、多态。
4.类的作用域
类定义了一个新的作用域,类的所有成员都在类的作用域中,在类体外定义成员,需要使用::作用域解释符指明成员属于那个领域。
5.类的实例化
用类类型创建对象的过程,称为类的实例化。
1.类只是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配内存来储存
2.一个例可以实例多个对象,实例化出的对象,占用实际的物理空间,存储类的成员变量
6.类对象的模型
6.1计算类对象的大小
class Date {
public:
void Init(int year, int month, int day);
private:
int _year;
int _month;
int _day;
};
上图定义的一个日期类,当这个类实例化一个对象后,这个对象所占的内存是多少?
很明显,实例化出来的对象的内存是12,而对象的成员变量所占的的内存刚好是12(和C语言中算结构体大小的方法一样不会结构体对齐计算的可以参考这篇文章自定义类型:那些容易出错的地方_m0_56695823的博客-CSDN博客),这刚好说明类的大小和成员函数没有关系,也就是说类的大小之和类中成员变量有关系。
为什么类的成员函数不存放在类中:因为调用同一份函数,如果此种方式存储,当一个类创建多个对象时,每一个对象中保存一份代码,相同代码保存多次,浪费空间。
对象中成员函数存放于代码段(常量区)
7.this指针
7.1 this指针的作用
先定义一个日期类
class Date {
public:
void display()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
void InitDate(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
d1.InitDate(2022, 2, 8);
Date d2;
d2.InitDate(1, 2, 3);
}
类Date中有两个成员函数,那当d1调用InitDate函数的时候,该函数是如何知道应该对d1进行设置,而不是d2呢?
C++中通过引入this指针来解决该问题,即C++给每一个“非静态成员函数”增加一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有成员变量的操作,都是通过该指针取访问,只不过所有的操作对用户都是隐藏的,即用户不需要来传递,编译器自动完成。
7.2 this的特性
1.this指针的类型:*const
2.只能在“成员函数”的内部使用
3.this指针本质上其实是一个成员函数的形参,是对象调用成员函数时,将对象地址作为实参传递给this形参,所以对象中不存储this指针。
4.this指针是成员函数第一个隐含的指针形参,调用成员函数时,不能显示实参传给this,在定义成员函数时,不能显示声明形参this。
7.3 this指针存放位置
转到反汇编后观察到,this指针存放在ecx寄存器中
7.4this易错点
首先p虽然是空指针,但是p调用的函数不会编译报错,因为空指针不是语法错误,编译器不会检查出来。其次,p调用成员函数不会出现空指针访问,因为成员函数没有存在于对象里面。所以这个程序会正常运行。
程序会崩,因为当调用成员函数display是没有问题的,但是,当输出_year时是会报错的,因为成员变量_year存在于类中。