类是用来描述对象的,对象有什么属性,有什么功能
基本概念
对象:属性(数据)+功能(以函数方式体现)
类:是对 对象的描述
C++中struct和class都能定义类,但两者类中成员的默认访问权限不同
- struct定义的类默认权限是public
- class定义的类默认权限是private
- C和C++中的struct没有可比性,因为两者含义不一样;
在C++中可以称之为结构体,但基本都称其为类,本质已经不同- C语言中,结构体定义出来的变量叫结构体变量;
C++中结构体定义出来的变量叫对象,结构体也被称为类(类型)
访问权限:限定类中的成员能否直接在类外来使用
public:公有 | 可以在类外直接访问 |
---|---|
private:私有 | 不能直接在类外访问 |
protected:保护 | 不能直接在类外访问 |
类中所有放置的内容称为当前类的成员:
类中的成员都是声明
成员变量 | 表示对象相关的数据 |
---|---|
成员函数 | 描述对象的行为或者功能 |
注:
- 成员函数可以定义在成员变量之前(编译器先排查成员变量)
成员变量是成员函数的全局变量,可以在各成员函数中使用- 成员函数可以在类外和类内定义,在类外定义时要在函数返回值后,函数名前加(类名::),不然编译器会将其当做全局函数,函数内部的变量就会在全局作用域中寻找,没有就会报错。
- 在类里面定义的函数编译器默认是内联函数
调用类中的成员需要通过:对象.成员 的方式调用
面向对象的三大特性:封装,继承,多态:
类和对象就是 → 封装:
- 将数据和操作数据的方法进行结合(用类结合);
- 隐藏对象的属性和实现细节(类中的访问权限),仅对外公开接口来和对象进行交互
类与对象
定义了一个新的类型,就相当于定义了一个新的作用域
类的实例化:用类类型创建对象的过程
- 类是用来描述对像,
- 对象是类实例化的结果
- 类中不能直接放数据,
- 数据都存放在对象中
类的特殊性质
两个对象d1和d2中的数据不同,调用方法相同,所以每个对象没有必要将函数都保存进去;
函数都在代码段保存
如果在定义对象时,对象中还包括相应函数,那么每定义一个对象就会占用许多空间,所以成员函数不存在对象中,对象中只存储数据,方法存储在另外的位置;
那么在调用时,对象应该如何找到相应的方法呢?
- 编译器要先对代码进行编译,编译时要将源文件编译(不对头文件编译,预处理会将头文件展开);
- 每个源文件编译完后会生成一个 .obj的目标文件,编译器还要将目标文件进行链接(链接的过程就是确定函数地址);
- 执行该可执行程序时,就已经得到了函数地址
类的大小
- 通过sizeof计算一个类,类的大小只和成员变量有关,
- 也就是说,计算类的大小就是计算类中所有非静态成员变量所占字节数
- 计算时注意内存对齐
空类的大小:
- 在主流编译器中(vs/g++),类中只有成员函数而无成员变量和空类的大小都为1个字节;
- 这是为了防止在开辟空间时,空类创造的不同对象在同一位置,导致编译器无法区分
截取上述部分代码
void SetDate(int year , int month , int day)
{
_year = year;
_month = month;
_day = day;
}
int main()
{
Date d1, d2;
d1.SetDate(2018,5,1);
d2.SetDate(2018,7,1);
return0;
}
this指针
类创建一个对象后,该指针就指向当前的对象
因为作用域的问题,对象在主函数中,不能用&对象在类中传参
- this 指针只能在非静态成员函数中使用,静态成员函数没有隐式的 this 指针
- this 指针不能被显式地修改,因为它指向的是当前对象,而对象的地址是不能被改变的
- this是指向当前对象的指针,当一个成员函数被调用时,编译器会自动向成员函数传递一个指向调用该函数的对象的指针
- return *this; 的形式返回当前对象本身,方便链式调用
this特点:
- this相当于引用
- this指针的类型:类类型* const,指向不能改变
- 只能非静态成员函的内部使用 ;
- this指针本质上是一个成员函数的形参,
对象调用成员函数时,将对象地址作为实参传递给this 形参,所以对象中不存储this指针;- this指针是成员函数第一个隐含的指针形参,(vs环境下)一般情况由编译器通过ecx寄存器自动传递,不需要用户传递;
- this的所有操作对用户是透明的,用户不需要来传递,编译器自动完成;
- 每个非静态成员函数参数部分就有一个this指针(this是第一个参数)
this指针的空间在栈上:
- this 指针本身并不是对象的一部分,而是成员函数的一个隐式参数
因此它通常被实现为一个指向对象内存空间的指针。在大多数情况下,这个指针被分配在调用栈上- 无论对象是在栈、堆、全局区上分配的,this 指针只是指向对象所在的内存空间,并不代表 this 指针本身的内存空间
是由编译器来决定在哪里分配这个指针的内存空间
验证:vs中是不能直接打印this指针的地址(因为指针变量不是左值,&必须是左值才行),应对this指针取别名后,再对该引用的地址进行打印
this指针为空时
进程虚拟地址空间