【个人网站】ctrlx.life 【联系方式】微信:gitctrlx 【软件技能】前端,C++,Python,研究网络工程,数据结构与算法。
C/CPP基础练习题多维数组,矩阵转置,杨辉三角详解
C/C++ 模板类模板与函数模板区别,以及用法详解
C/C++普通函数与函数模板的区别,调用规则,模板局限性
C++泛型编程,模板(一)函数模板
C/CPP基础练习题(二)简单循环(2 + 22 + 222…;斐波那契数列)
C/CPP基础练习题(一)运算符,判断
C/C++size(),sizeof(),length(),strlen() 对比分析详解
C标准库atoi, atof, atol, atoll(C++11标准) 函数,以及sprintf、sscanf函数,用sstream类,实现C++中int和string的互相转换
文本文件 写文件 写文件步骤如下: 1. 包含头文件 #include <fstream> 2. 创建流对象 ofstream ofs; 3. 打开文件 ofs.open("文件路径",打开方式); 4. 写数据 ofs << "写入的数据"; 5. 关闭文件 ofs.close(); 文件打开方式: 打开方式 解释 ios::in 为读文件而打开文件 ios::out 为写文件而打开文件 ios::ate 初始位置:文件尾 ios::app 追加方式写文件 ios::trunc 如果文件存在先删除,再创建 ios::binary 二进制方式
例描述:** 电脑主要组成部件为 CPU(用于计算),显卡(用于显示),内存条(用于存储) 将每个零件封装出抽象基类,并且提供不同的厂商生产不同的零件,例如Intel厂商和Lenovo厂商 创建电脑类提供让电脑工作的函数,并且调用每个零件工作的接口 测试时组装三台不同的电脑进行工作
虚析构和纯虚析构 多态使用时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构代码 解决方式:将父类中的析构函数改为虚析构或者纯虚析构 虚析构和纯虚析构共性: • 可以解决父类指针释放子类对象 • 都需要有具体的函数实现 虚析构和纯虚析构区别: • 如果是纯虚析构,该类属于抽象类,无法实例化对象
纯虚函数和抽象类 在多态中,通常父类中虚函数的实现是毫无意义的,主要都是调用子类重写的内容 因此可以将虚函数改为纯虚函数 纯虚函数语法:virtual 返回值类型 函数名 (参数列表)= 0 ; 当类中有了纯虚函数,这个类也称为==抽象类== 抽象类特点: • 无法实例化对象 • 子类必须重写抽象类中的纯虚函数,否则也属于抽象类
多态分为两类 • 静态多态: 函数重载 和 运算符重载属于静态多态,复用函数名 • 动态多态: 派生类和虚函数实现运行时多态 静态多态和动态多态区别: • 静态多态的函数地址早绑定 - 编译阶段确定函数地址 • 动态多态的函数地址晚绑定 - 运行阶段确定函数地址 下面通过案例进行讲解多态
继承中的对象模型 问题:从父类继承过来的成员,哪些属于子类对象中? 示例: class Base { public: int m_A; protected: int m_B; private: int m_C; //私有成员只是被隐藏了,但是还是会继承下去
继承的好处:==可以减少重复的代码== class A : public B; A 类称为子类 或 派生类 B 类称为父类 或 基类 派生类中的成员,包含两大部分: 一类是从基类继承过来的,一类是自己增加的成员。 从基类继承过过来的表现其共性,而新增的成员体现了其个性。 继承方式 继承的语法:class 子类 : 继承方式 父类 继承方式一共有三种: • 公共继承 • 保护继承 • 私有继承
关系运算符重载 作用:重载关系运算符,可以让两个自定义类型对象进行对比操作
赋值运算符重载 c++编译器至少给一个类添加4个函数 1. 默认构造函数(无参,函数体为空) 2. 默认析构函数(无参,函数体为空) 3. 默认拷贝构造函数,对属性进行值拷贝 4. 赋值运算符 operator=, 对属性进行值拷贝 如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题 示例:
如果返回值是引用,局部对象在当前成员函数执行完后释放,再返回局部对象的引用就是非法操作。如果返回值是一个值,实际上返回的是一个值的副本,因为返回是一个拷贝构造过程,原来的释放了,但是拷贝了一份新的,不受成员函数释放的影响。(详细见前面文章回顾) 这里可以直接 new 一个类,然后就可以返回引用了。
左移运算符重载 作用:可以输出自定义数据类型 1.利用成员函数实现左移运算符 class Person { public: Person(int a, int b) { this->m_A = a; this->m_B = b; } //利用成员函数实现左移运算符:p.operator<<(cout)简化版本p << cout 无法实现cout在左边。 //成员函数 p << p 不是我们想要的效果,想要cout<<p
加号运算符重载 作用:实现两个自定义数据类型相加的运算 1.成员函数实现 + 号运算符重载 2.全局函数实现 + 号运算符重载 3.运算符重载 可以发生函数重载
在程序里,有些私有属性 也想让类外特殊的一些函数或者类进行访问,就需要用到友元的技术 友元的目的就是让一个函数或者类 访问另一个类中私有成员 友元的关键字为 ==friend== 友元的三种实现 • 全局函数做友元 • 类做友元 • 成员函数做友元 全局函数做友元
成员变量和成员函数分开存储 在C++中,类内的成员变量和成员函数分开存储 只有非静态成员变量才属于类的对象上 class Person { public: Person() { mA = 0; } //非静态成员变量占对象空间 int mA; //静态成员变量不占对象空间 static int mB; //函数也不占对象空间,所有函数共享一个函数实例 ——关键,原因见下讲。 void func() {
对象的初始化和清理 • 生活中我们买的电子产品都基本会有出厂设置,在某一天我们不用时候也会删除一些自己信息数据保证安全 • C++中的面向对象来源于生活,每个对象也都会有初始设置以及 对象销毁前的清理数据的设置。 构造函数和析构函数 对象的初始化和清理也是两个非常重要的安全问题 一个对象或者变量没有初始状态,对其使用后果是未知
封装意义一: 在设计类的时候,属性和行为写在一起,表现事物 语法: class 类名{ 访问权限: 属性 / 行为 }; 示例1:设计一个圆类,求圆的周长
生活中充满复杂性,处理复杂性的方法之一就是简化和抽象。在计算中,为了根据信息与用户之间的接口来表示它,抽象是至关重要的。将问题的本质特征抽象出来,并根据特征来描述解决方案。抽象往往是用户定义类型的捷径,在C++中用户定义类型指的就是实现抽象接口的类设计。
深拷贝与浅拷贝 深浅拷贝是面试经典问题,也是常见的一个坑 浅拷贝:简单的赋值拷贝操作 深拷贝:在堆区重新申请空间,进行拷贝操作
函数重载概述 作用:函数名可以相同,提高复用性 函数重载满足条件: • 同一个作用域下 • 函数名称相同 • 函数参数类型不同 或者 个数不同 或者 顺序不同 注意: 函数的返回值不可以作为函数重载的条件
多情况使用场景 demo1地址和值都不可以修改 只读不可修改,防止误操作 demo2指针常量,地址可变,值不可变 用于在函数体内给函数体外的变量更换别名,且别名只在函数体内有效 demo3常量指针,地址不变,值可以变 正常的值传递,可以简化指针值传递的繁琐操作
C++程序在执行时,将内存大方向划分为**5个区域** 运行前: - 代码区:存放**函数体的二进制代码**,由操作系统进行管理的 - 全局区(静态区):存放**全局变量和静态变量以及常量** - 常量区:**常量**存储在这里,不允许修改 运行后: - 栈区:由编译器自动分配释放, 存放**函数的参数值**,**局部变量等** - 堆区:**由程序员分配和释放**,若程序员不释放,程序结束时由操作系统回收