个人总结的一些C++基础理论
她比卡莎更美 人气:0我自己整理的一些C++基础理论知识,面试的同学可以用到:
主要是针对那些基础理论知识比较薄弱的同学吧,希望会对大家面试有些帮助,排版什么的有点乱,大家多多包涵:
类和对象-封装-属性和行为作为整体
- C++认为万事万物都皆为对象,对象上有其属性和行为
- 封装的意义一:a. 将属性和行为作为一个整体,表现生活的事物b. 将属性和行为加以权限控制
在设计类的时候,属性和行为写在一起,表现事物语法:class类名 { 访问权限: 属性 / 行为 };类和对象-封装-访问权限 - 封装意义二:类在设计时,可以把属性和行为放在不同的权限下,加以控制
- 访问权限三种:a. public 公共权限
b. protected 保护权限
c. private 私有权限类
对象-封装-C++中class和strcut的区别
在C++中struct和class唯一的区别就在于默认的访问权限不同
区别:a. struct默认权限为公共
b. class默认权限为私有类和对象-封装-成员属性私有化优点 - 1:将所有成员属性设置为私有,可以自己控制读写权限优点
2:对于写权限,我们可以检测数据的有效性类和对象-对象特征-构造函数和析构函数 - 对象的初始化以及清理:C++中的面向对象来源于生活,每个对象也都有初始设置以及,对象销毁前的清理数据的设置;如果我们不提供构造和析构,编译器会提供编译器提供的构造函数和析构函数是空实现
- 构造函数:作用在于创建对象时对对象的成员属性赋值,构造函数由编译器自动调、用, 无需手动调用;
- 析构函数:作用在于对象销毁系统前自动调用执行一些清理工作类和对象-对象特征-函数的分类以及调用
- 两种分类方式按参数分为:有参构造和无参构造;按类型分为:普通构造和拷贝构造;
- 三种调用方式:括号法;显示法;隐式转换法;类和对象-对象特征-拷贝构造函数调用时机C++中拷贝构造函数调用时机通常有三种:
1.使用一个已创建完毕的对象来初始化一个新对象
2.值传递的方式给函数参数传值
3.以值方式返回局部对象类和对象-对象特征-构造函数调用规则默认情况下,C++编译器至少给一个类添加三个函数 - 默认构造函数(无参,函数体为空);
- 默认析构函数(无参,函数体为空);
- 默认拷贝构造函数,对属性进行值拷贝;构造函数调用规则如下:
1.如果用户自定义有参构造函数,C++不再提供默认无参构造,但是会提供默认拷贝构造
2.如果用户自定义拷贝构造函数,C++不会提供默构造函数类和对象-对象特征-深拷贝与浅拷贝
浅拷贝:简单的赋值拷贝工作
深拷贝:在堆区重新申请空间,进行拷贝操作类和对象-对象特征-静态成员-静态成员函数 - 静态成员就是在成员变量和成员函数加上static关键字,称为静态成员
- 静态成员变量a. 所有对象共享同一份数据b. 在编译阶段分配内存c. 类内声明,类外初始化
- 静态成员函数a. 所有对象共享同一函数b. 静态成员函数只能访问静态成员变量类和对象-对象特征-成员变量和成员函数分开存储
- 在C++中,类内成员变量和成员函数分开存储
- 只有非静态成员变量才属于类的对象上
- 空对象占用内存空间为:1C++编译器会给每个空对象也分配一个字节空间,是为了区分空对象占内存的位置每个空对象也应该有独一无二的内存地址类和对象-对象特征-this指针的用途
- C++通过提供特殊的对象指针,this指针,解决上述问题,this指针指向被调用的成员函数所属的对象
- This指针是隐含每一个非静态成员函数内的一种指针
- This指针不需要定义,直接使用即可
- This指针的用途:a. 当形参和成员变量同名时,可用this指针来区分b. 在类的非静态成员函数中返回对象本身,可使用return *this 类和对象-对象特征-空指针访问成员函数
- C++中空指针也是可以调用成员函数的,但是也要注意有莫有用到this指针
- 如果用到this指针,需要加以判断保证代码的健壮性类和对象-对象特征-const修饰成员函数
- 常函数:a. 成员函数后加const后我们称这个函数为常函数b. 常函数内不可以修改成员属性c. 成员属性声明时加关键字mutable后,在常函数中依然可以修改
- 常对象:a. 声明对象前const称该对象为常对象b. 常对象只能调用常函数
- This指针的本质 是指针常量 指针的指向是不可修改的 Const Person * const this;在成员函数后面加const,修饰的是this指向,让指针指向的值也是不可修改的类和对象-友元-全局函数做友元1. 友元的目的就是让一个函数或者类,访问另一个类中私有成员
- 友元关键字friend
- 友元的三种实现a. 全局函数做友元b. 类做友元c. 成员函数做友元类和对象-C++运算符重载-加号运算符重载
- 运算符重载概念:对已有运算符重新定义,赋予其另一种功能,以适应不同的数据类型
- 作用:实现两个自定义数据类型相加的运算
- . 通过自己写的成员函数,实现两个对象相加的属性后返回新的对象
- 通过成员函数重载+号;通过全局函数重载+号 类和对象-C++运算符重载-左移运算符重载作用:可以输出自定义数据类型
- 不会利用成员函数重载<<运算符,因为无法实现cout在左侧
- 只能利用全局函数重载<<运算符类和对象-C++运算符重载-递增运算符重载作用:通过重载递增运算符,实现自己的整型数据
- 前置递增:重载前置++运算符 返回引用是为了一直对一个数据进行递增操作
- 后置递增:void operator(int) int代表占位参数,可以用于区分前置和后置递增类和对象-C++运算符重载-赋值运算符重载默认情况下,C++编译器至少给一个类添加三个函数
- 默认构造函数(无参,函数体为空);
- 默认析构函数(无参,函数体为空);
- 默认拷贝构造函数,对属性进行值拷贝;
- 赋值运算符 operator=,对属性进行值拷贝;总结:如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题类和对象-C++运算符重载-关系运算符重载作用:重载关系运算符,可以让两个自定义数据类型对象进行对比操作类和对象-C++运算符重载-函数调用运算符重载
- 函数调用运算符()也可以重载
- 由于重载后使用的方式非常像函数的调用,因此被称为仿函数
- 仿函数莫有固定写法,非常灵活//重载关系运算符 bool operator==(Person &p) { if (this->m_Name == p.m_Name&&this->m_Age == p.m_Age) { return true; } return false; }类和对象-继承-基本语法优点:减少重复代码类和对象-继承-继承方式语法:class 子类 :继承方式 父类继承的方式有三种:
- 公共继承
- 保护继承
- 私有继承
- 公共继承:父类的公共权限,在子类依然是公共权限 父类的保护权限,在子类依然是保护权限 父类的私有成员 子类访问不到保护继承:父类的公共权限,在子类变为保护权限父类的保护权限,在子类依然是保护权限父类的私有成员 子类访问不到私有继承:父类的公共权限,在子类变为私有权限父类的保护权限,在子类变为私有权限父类的私有成员 子类访问不到 类和对象-继承-继承中的对象模型
- 父类中所有非静态成员都会被子类继承下去
- 父类中的成员属性 是被编译器给隐藏了,因此是访问不到,但确实是被继承下去了类和对象-继承-构造和析构顺序
- 子类继承父类后,当创建子类对象,也会调用父类的构造函数
- 继承中的构造和虚构顺序如下:先构造父类,再构造子类,析构的顺序与构造的顺序相反类和对象-继承-同名成员处理问题:当子类与父类出现同名成员,如何通过子类对象,访问到子类或父类中同名的数据呢?
- 访问子类同名成员 直接访问即可
- 访问父类同名成员 需要加作用域
- 当子类与父类拥有同名的成员函数,子类会隐藏父类中同名成员函数,加作用域可以访问到父类中同名函数类和对象-继承-同名静态成员处理问题:继承中同名的静态成员在子类对象上如何进行访问?
- 通过对象访问
- 通过类名访问静态成员和非静态成员出现同名,处理方式一致
- 访问子类同名成员 直接访问即可
- 访问父类同名成员 需要加作用域
- 当子类与父类拥有同名的成员函数,子类会隐藏父类中同名成员函数,加作用域可以访问到父类中同名函数类和对象-继承-继承语法
- C++允许一个类继承多个类
- 多继承可能会引发父类中有同名成员出现,需要加作用域区分
- 不建议使用多继承类和对象-继承-菱形继承问题以及解决方法菱形继承概念:
- 两个派生类继承同一个基类
- 又有某个类同时继承两个派生类
- 这种继承称为菱形继承或者钻石继承类和对象-多态-多态的基本语法多态分为两类:
- 静态多态 函数重载和运算符重载属于静态多态,复用函数名
- 动态多态 派生类和虚函数实现运行多态静态多态和动态多态的区别:
- 静态多态的函数地址早绑定 编译阶段确定函数地址
- 动态多态的函数地址晚绑定 运行阶段确定函数地址Speak就是虚函数函数前面加上virtual关键字,变成虚函数,那么编译器在编译时就不能确定函数调用了类和对象-多态-多态的原理剖析多态满足条件: 有继承关系 子类重写父类中的虚函数多态使用条件: 父类指针或引用指向子类对象重写:函数返回值类型 函数名 参数列表 完全一致称为重写类和对象-多态-纯虚函数和抽象类
- 在多态中,通常父类中虚函数的实现是毫无意义的,主要都是调用子类重写的内容
- 可以将虚函数改为纯虚函数
- 纯虚函数语法:virtual 返回值类型 函数名 (参数列表) = 0;
- 当类中有了纯虚函数,这个类也被称为抽象类;
- 抽象类特点:a. 无法实例化对象b. 子类必须重写抽象类中的纯虚函数,否则也属于抽象类类和对象-多态-虚析构和纯虚析构
- 多态使用时,如果子类有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构代码
- 解决方式:将父类中的析构函数改为虚析构或者纯虚析构
- 虚析构和纯虚析构共性a. 可以解决父类指针释放子类对象b. 都需要有具体的函数实现
- 虚析构和纯虚析构共性如果是纯虚析构,该类属于抽象类,无法实例化对象
- 虚析构语法:Virtual ~类名(){}
- 纯虚析构语法:Virtual ~类名()= 0;类名::类名(){}
加载全部内容