2.C++随手简记(二)

C++学习篇2

第一部分:内存分区模型

C++程序执行时内存分为四个区域:

  1. 代码区:存放函数体的二进制代码,操作系统管理,特点是共享和只读。
  2. 全局区:存放全局变量、静态变量和常量,程序结束后操作系统释放。
  3. 栈区:编译器自动分配释放,存放函数参数和局部变量,注意不要返回局部变量地址。
  4. 堆区:程序员分配和释放,使用newdelete操作符,若不释放,程序结束时操作系统回收。

第二部分:引用

引用是给变量起别名的一种机制:

  • 基本使用:通过数据类型 &别名 = 原名语法定义。
  • 注意事项
    • 引用必须初始化。
    • 初始化后,引用不可以改变。
  • 引用作为函数参数:简化指针修改实参,通过const修饰防止误操作。
  • 引用作为函数返回值:可以返回局部变量的引用,但不要返回局部变量的引用。
  • 引用的本质:在C++内部实现是指针常量。
  • 常量引用:修饰形参,防止误操作。

第三部分:函数提高

函数在C++中可以有默认参数、占位参数和重载:

  • 函数默认参数:形参可以有默认值,简化函数调用。
  • 函数占位参数:用于必须填补的位置参数。
  • 函数重载:允许函数名相同,参数类型或个数不同,提高复用性。返回值不可以作为重载条件。

第四部分:类和对象

面向对象的三大特性:封装、继承、多态。

  • 封装:将属性和行为作为一个整体,加以权限控制。
    • 访问权限:publicprotectedprivate
    • structclass的区别在于默认访问权限。
    • 成员属性设置为私有,控制读写权限,检测数据有效性。
  • 对象的初始化和清理
    • 构造函数和析构函数:自动调用,完成对象初始化和清理。
    • 构造函数分类:有参、无参(默认)、普通构造、拷贝构造。
    • 拷贝构造函数调用时机:初始化新对象、值传递给函数参数、返回局部对象。
    • 构造函数调用规则:用户定义有参构造函数时,编译器不提供默认无参构造函数。
    • 深拷贝与浅拷贝:深拷贝重新申请空间,浅拷贝简单赋值。
    • 初始化列表:使用构造函数初始化属性。
    • 类对象作为类成员:对象成员的构造和析构顺序。
    • 静态成员:静态成员变量和函数,所有对象共享。

4.1 封装

封装是面向对象编程的核心概念之一,它允许将数据(属性)和操作这些数据的代码(行为)组合在一起。封装提供了以下几个好处:

  • 数据隐藏:通过访问修饰符(如private),可以隐藏类的内部实现细节。
  • 数据保护:确保类的状态只能通过定义良好的接口进行修改。
  • 易于使用:提供简单直观的接口供外部访问。

4.2 对象的初始化和清理

对象的生命周期包括创建和销毁两个阶段。C++提供了构造函数和析构函数来管理这两个阶段:

  • 构造函数:在对象创建时自动调用,用于初始化对象的状态。
  • 析构函数:在对象销毁前自动调用,用于执行清理工作,如释放分配的资源。

4.3 构造函数和析构函数

构造函数和析构函数是类的特殊的成员函数:

  • 构造函数:没有返回类型,也没有参数(尽管可以有默认参数),其名称与类名相同。构造函数可以被重载,以支持不同的初始化方式。
  • 析构函数:同样没有返回类型,名称前加~符号,用于对象生命周期结束时的清理。

4.4 拷贝构造函数

拷贝构造函数用于通过现有对象初始化新对象。它有三个特点:

  • 参数:接受一个常量引用类型的参数。
  • 用途:用于实现对象的深拷贝或浅拷贝。
  • 调用时机:对象作为参数传递给函数、返回对象类型的函数值、使用对象初始化另一个对象时。

4.5 深拷贝与浅拷贝

  • 浅拷贝:只复制对象的直接成员,如果对象包含指针,那么拷贝后两个对象将共享同一块内存。
  • 深拷贝:为对象的每个成员创建新的内存,即使成员是指针,也会复制指针指向的内容。

4.6 初始化列表

初始化列表用于在构造函数中初始化类的成员变量。它提供了一种更高效、更清晰的方式来初始化对象。

4.7 静态成员

静态成员属于类本身,而不是类的任何特定对象:

  • 静态成员变量:所有对象共享同一份数据。
  • 静态成员函数:所有对象共享同一个函数,只能访问静态成员变量。

4.8 类对象作为类成员

当一个类的对象作为另一个类的成员时,成员对象的构造和析构顺序遵循特定的规则:先构造成员对象,后构造包含它的对象;析构顺序与之相反。

第五部分:C++对象模型和this指针

  • 成员变量和成员函数分开存储,非静态成员变量属于对象。 this指针是指向当前对象的指针,它允许成员函数访问和修改其所属对象的状态。this指针的主要用例包括:
  • 区分成员变量和局部变量:当成员函数中的局部变量与成员变量同名时,使用this指针来区分。
  • 返回对象本身:在成员函数中使用return *this可以返回对象的引用。
  • 空指针访问成员函数:可以调用,但需注意this指针的使用。
  • const修饰成员函数:常函数不可修改成员属性,mutable关键字允许在常函数中修改。

第六部分:友元

友元是C++中的一个特殊概念,它允许非成员函数或另一个类的成员函数访问类的私有或保护成员:

  • 全局函数作为友元:可以访问类的私有和保护成员。
  • 类作为友元:友元类的所有成员函数都可以访问声明它的类的私有和保护成员。
  • 成员函数作为友元:特定类的成员函数可以访问另一个类的私有和保护成员。

第七部分:运算符重载

运算符重载允许为自定义类型定义运算符的行为:

  • 加号运算符:允许两个自定义类型对象相加。
  • 左移运算符:通常与ostream结合使用,用于输出自定义类型。
  • 递增运算符:可以重载为前置或后置,改变对象的状态。
  • 赋值运算符:需要特别关注深浅拷贝问题。
  • 关系运算符:允许比较两个自定义类型对象。
  • 函数调用运算符:允许对象像函数一样被调用,称为仿函数。

第八部分:继承

继承减少重复代码,基类和派生类的概念:

  • 继承的基本语法:class 子类 : 继承方式 父类
  • 继承方式:公共继承、保护继承、私有继承。
  • 继承中的对象模型:私有成员也被继承。
  • 继承中的构造和析构顺序:先父类构造,后子类构造,析构相反。
  • 继承同名成员处理:子类可以直接访问,父类需要加作用域。
  • 继承同名静态成员处理:通过对象或类名访问。
  • 多继承语法:可能引发同名成员问题,使用作用域区分。
  • 菱形继承:两个派生类继承同一个基类,一个类继承这两个派生类。

第九部分:多态

9.1 多态的基本概念

多态是面向对象编程的核心特性之一,它允许派生类重写基类的虚函数,使得同一个接口可以有不同的实现。多态使得代码更加灵活和可扩展。

9.2 静态多态与动态多态

  • 静态多态:也称为早绑定,编译时确定调用哪个函数,如函数重载和运算符重载。
  • 动态多态:也称为晚绑定,运行时确定调用哪个函数,主要通过虚函数实现。

9.3 虚函数和抽象类

  • 虚函数:在基类中使用virtual关键字声明的函数,可以被子类重写。
  • 抽象类:包含至少一个纯虚函数的类,不能实例化,通常作为其他类的接口。

9.4 多态的使用

多态的使用通常涉及以下几个步骤:

  1. 定义基类:包含虚函数。
  2. 派生类:重写基类的虚函数。
  3. 使用基类指针或引用:指向派生类对象,实现多态。

9.5 纯虚函数和抽象类

  • 纯虚函数:使用virtual 返回类型 函数名() = 0;声明,没有实现体。
  • 抽象类:包含纯虚函数的类,不能被实例化,通常用作接口。

9.6 虚析构和纯虚析构

  • 虚析构:在基类中声明virtual ~类名() {},确保通过基类指针删除派生类对象时正确调用派生类的析构函数。
  • 纯虚析构:声明为virtual ~类名() = 0;,使得类成为抽象类,强制派生类提供析构函数的定义。

第十部分:文件操作

10.1 文件概述

文件是数据的持久化存储,C++提供了丰富的文件操作API。

10.2 文件类型

  • 文本文件:以ASCII码形式存储,可读性强。
  • 二进制文件:以二进制形式存储,存储效率高,但可读性差。

10.3 文件操作类

  • ofstream:用于文件写操作。
  • ifstream:用于文件读操作。
  • fstream:支持文件的读写操作。

10.4 文本文件操作

10.4.1 写文件

写文件的基本步骤:

  1. 包含头文件#include <fstream>
  2. 创建ofstream对象。
  3. 使用open函数打开文件。
  4. 使用<<运算符写入数据。
  5. 使用close函数关闭文件。

10.4.2 读文件

读文件的基本步骤:

  1. 包含头文件#include <fstream>
  2. 创建ifstream对象。
  3. 使用open函数打开文件。
  4. 读取数据,可以使用>>运算符或成员函数如getline
  5. 使用close函数关闭文件。

10.5 二进制文件操作

10.5.1 写文件

二进制写文件使用ofstream对象的write成员函数:

ofstream ofs("filename", ios::binary);
char buffer[] = {...}; // 数据缓冲区
ofs.write(buffer, sizeof(buffer));

10.5.2 读文件

二进制读文件使用ifstream对象的read成员函数:

ifstream ifs("filename", ios::binary);
char buffer[100]; // 数据缓冲区
ifs.read(buffer, sizeof(buffer));

10.6 文件打开模式

  • ios::in:打开文件用于读取。
  • ios::out:打开文件用于写入。
  • ios::app:每次写操作后定位到文件末尾。
  • ios::trunc:如果文件存在,先截断文件再写入。
  • ios::binary:以二进制模式打开文件。

10.7 文件流的状态检查

使用is_open函数检查文件是否成功打开,使用eof检查是否到达文件末尾。

10.8 文件流的异常处理

C++标准库提供了一套异常处理机制,可以在文件操作中捕获和处理异常。

ddaf2e7924d54528a92e25df57a387f5.png

 

  • 25
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式&机器人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值