当先锋百科网

首页 1 2 3 4 5 6 7

C++对象模型和this指针

4.3.1 成员变量和成员函数分开存储

在C++中,类内的成员变量和成员函数分开存储

只有非静态成员变量才属于类的对象上

 空类(类里面是空的),空对象占用内存空间为:1字节。

静态成员变量,类内声明,类外初始化。

4.3.2 this指针概念

this指针指向被调用的成员函数所属的对象。

4.3.3 空指针访问成员函数

C++中空指针也是可以调用成员函数的,但是也要注意有没有用到this指针

4.3.4 const修饰成员函数

常函数

  • 成员函数后加const后我们称为这个函数是常函数
  • 常函数内不可以修改成员属性
  • 成员属性声明时加关键字mutable后,在常函数中依然可以修改
//常函数
void func() const
{
    cout << "常函数" << endl;
}

常对象

  • 声明对象前加const称该对象为常对象
  • 常对象只能调用常函数

this指针的本质  是指针常量  指针的指向是不可以修改的。

常对象不可以调用普通成员函数,因为普通成员函数可以修改属性。

4.4 友元

友元的目的就是让一个函数或者类 访问另一个类中私有成员

友元的关键字为friend

友元的三种实现

  • 全局函数做友元
  • 类做友元
  • 成员函数做友元

4.5 运算符重载

4.5.1 赋值运算符重载

C++编译器至少各一个类添加4个函数

  1. 默认构造函数(无参,函数体为空)
  2. 默认析构函数(无参,函数体为空)
  3. 默认拷贝构造函数,对属性进行值拷贝
  4. 赋值运算符operator=,对属性进行值拷贝

类名后面跟一个小括号,称之为匿名对象,执行完后立即释放。

如:

Person()   其中Person是类名

4.6 继承

继承的好处,减少重复代码

继承方式:

父类中所有非静态成员属性都会被子类继承下去。

父类中私有成员属性,是被编译器给隐藏了,因此是访问不到,但是确实被继承下去了。

 继承中的构造和析构顺序如下:

先构造父类,再构造子类,析构的顺序与构造的顺序相反。

 4.6.1 继承中的同名静态成员处理

 4.7 多态

4.7.1 多态的基本概念

多态分为两类

  • 静态多态:函数重载 和 运算符重载属于 静态多态,复用函数名
  • 动态多态:派生类和虚函数实现运行时多态

静态多态和动态多态区别:

  • 静态多态的函数地址早绑定 - 编译阶段确定函数地址
  • 动态多态的函数地址晚绑定 - 运行阶段确定函数地址

动态多态满足条件

  1. 有继承关系
  2. 子类重写父类的虚函数

动态多态使用:父类的指针或引用 指向 子类对象。

重写:函数返回值类型 函数名 参数列表 完全一致,只有函数体中的内容不同 称为函数重写。

4.7.2 多态的原理剖析

 要想写多态,父类中需要写虚函数,子类需要对父类中的虚函数进行重写。

4.7.3 纯虚函数和抽象类

纯虚函数语法:virtual 返回值类型 函数名(参数列表) = 0;

当类中有了纯虚函数,这个类也称为抽象类

抽象类特点

  • 无法实例化对象
  • 子类必须重写抽象类中的纯虚函数,否则也属于抽象类

多态:一个接口有多种形态,由于你传入的对象不一样,但是都是同一个接口,去实现不同的功能。

4.7.4 虚析构和纯虚析构

在多态使用时,父类指针或引用指向子类对象,如果子类中有属性开辟到堆区,父类指针在delete的时候,父类指针无法释放子类中的析构代码。

父类指针在析构时候 不会调用子类中析构函数,导致子类如果有堆区属性,出现内存泄漏。

解决方式:将父类中的析构函数改为虚析构或者纯虚析构

1.父类中如果有纯虚函数,子类必须对父类中的纯虚函数进行函数重写,否则子类是抽象类,无法实例化;

2.父类中有纯虚析构,需要函数声明也需要函数实现,在类外部进行函数实现;

3.有了纯虚析构之后,这个类也属于抽象类,无法实例化对象。

 5 文件操作

程序运行时产生的数据都属于临时数据,程序一旦运行结束都会被释放。

通过文件可以将数据持久化

C++中对文件操作需要包含头文件<fstream>

文件类型分为两种:

  1. 文本文件:文件以文本的ASCII码形式存储在计算机中
  2. 二进制文件:文件以文本的二进制形式存储在计算机中,用户一般不能直接读懂它们

操作文件的三大类:

  1. ofstream:写操作
  2. ifstream:读操作
  3. fstream:读写操作

5.1 文本文件

 

 

  

 5.2 二进制文件