当前位置: 首页 > article >正文

期末速成C++【知识点汇总完】

目录

第一章

C++特点

命名空间-命名冲突

引用

new和delete

堆和栈 

缺省参数 

重载/隐藏/覆盖 

初始化方式

第二章

面向对象的三大特征

成员变量

成员函数:构造函数和析构函数

访问权限和继承方式

空类 

常const

静态static

友元friend 

第三章

重载 

重载为成员函数

类型转换运算符重载 

函数运算符的重载

第四章-子类父类 

第五章-virtual多态

第六章-模板

第七章-STL

第八章-文件IO

第九章-异常

第十章❗


第一章

C++特点

  • 同时支持四种编程范式面向过程、面向对象、泛型编程、函数式编程

  • 同C语言相比,适合开发大型应用程序(操作系统内核还是C语言)(多人同时开发namespace)(存在OOP)

  • 具有可复用、可维护、可扩展、灵活性好的特点(活字印刷)

  • 头文件:不带.h   math.h(cmath)string.h(cstring)

  • 关键字:都是小写。

命名空间-命名冲突

  •  const char*  char const*:常量指针:const 修饰的是指向的内容
  • char*const:指针常量:const修饰的是指针(指向的关系)
const char* p=”hello”;
char const* p=”hello”;

数组名 char arr[10];arr的实际类型是char* const

引用

函数参数

  • 实参就是形参;参数类型就是常引用类型。const vector<int>&
  • 常引用是常对象,常对象只能调用常函数const。重载自定义类型的operator<,常函数。(重载运算类的不能const)

函数返回值

  • 不能返回局部变量的引用

  • ostream& operator<<(ostream& out,const ......&){ return out; }  return *this

  • 前置++返回*this:是&
  • 后置++(int)返回是temp:不能是&
  • +重载,返回的是局部变量:不能是&

new和delete

new/delete和malloc/free不能混用
new/delete和new[]/delete[]是两对运算符
new[]/delete[]定义变长数组

int len=100;  //变量
Int* p=new int[len] //变长数组一定要用delete[]释放
p[i]和*(p+i)是等价的

堆和栈 

堆(malloc/new)

  •  一个进程只有一个堆。
  • 手动分配,手动回收。
  • 不能通过变量访问,只能通过指针间接访问。
  • new/delete
  • int* p = new int  //两段内存:栈:p☞堆:int

  • 每个函数的每一次运行,都会有一个独立的栈。
  • 放局部变量。
  • 自动分配,自动回收
  • 通过局部变量访问。

RAII资源获取即初始化Resource Acquisition is Initialization

在构造函数中去new,在析构函数中使用delete

缺省参数 

  • 优先写在声明里(定义不在写)(只能写一次)
  • 函数在给半缺省参数,必须是从右往左连续依次给出,不能间隔跳跃。(从第一个开始)
  • 调用函数传参:必须从左到右连续传参,不能跳跃。(从第一个开始)
        int add(int a=1,int b=2,int c=3) {return a+b+c;}
        add(1);  1 2 3
        add(1,1); 1 1 3
        add(1,1,1); 1 1 1


❌void Func2(int a, int b = 10, int c)
❌void Func2(int a=10, int b, int c = 20)

重载/隐藏/覆盖 

重载:同名函数,同一作用域,参数列表不同。

Int add(int a,int b);
Int add(int x,int y);//二者不构成重载

隐藏:同名函数,不是覆盖都是隐藏(不是virtual虚函数),父类子类。

class Base
{
     Int foo(int);//函数1
     Int fool(int,int);//函数2
};

Class Derived;public Base
{
     int fool(int,int);//函数3
};

1和2重载
1和3隐藏
2和3隐藏

覆盖:同名函数,多态,虚函数virtual,原型严格一致。 

class Base
{
     virtual Int foo(int,int);//函数1
};

Class Derived;public Base
{
     virtual int fool(int,int);//函数2
};

函数1和2覆盖
Base * pb=new Derived;
pb->foo(); //函数2

初始化方式

  • int a=100; //C语言

  • int b(100); //经典C++

  • int c{100}; //现代C++,统一初始化

  • 初始化的次数❓

Class foo{};
Foo a(1);//1
Foo a=1;//1
Foo a{1};//1
Foo* pf;//没有
Foo pf[10];//10次
Foo* pf[10];//一次没有

第二章

面向对象的三大特征

  • 封装:隐藏内部实现
  • 继承:实现代码复用
  • 多态:改写对象行为
  • 类中成员:成员变量(名词性的属性)和成员函数(动词性的行为)
  • 重载:代码间接,❌不是代码复用。

成员变量

成员可以是自身类型的指针或引用,不能包含自己。

class Foo{
Foo *pf;
Foo& rf;
Foo f;//❌
};

成员函数:构造函数和析构函数

  • 构造函数和析构函数和Seter/Geter

  • 构造函数:无参构造函数/带参构造函数/拷贝构造函数/类型转换构造函数
  • 析构函数
  • 构造函数的参数不能是自身类型。

  • 析构函数:释放对象

  • 析构函数的释放顺序和创建顺序相反

class MyString{
};

MyString() //无参构造函数
MyString(string str); //带参构造函数
MyClass(const MyString& other); //拷贝构造函数
~MyString(); //析构函数
virtual ~MyString(); //虚析构函数(父类是子类可以省略virtual)
MyString(const char* str);//类型转换构造函数

构造函数:创建和初始化对象

  • 默认构造函数

  • 无参构造函数

  • 默认拷贝构造函数:系统提供,按位拷贝,bit-by-bit,无参

  • 拷贝构造函数:一个参数,自身类型的引用(包括常引用,一般是常引用)

  • 类型转化构造函数:一个参数,不是自身类型,也不是自身类型的引用

1.无参构造函数调用的方式:
class Foo{
         Foo();
};
Foo a=10;
Fool* pb=new foo;
Foo f;
Foo af[10];

2.带参构造函数调用方式:
class Foo{
         Foo(int other);
};
Foo a=10;
Foo* pb=new foo(10);
Foo f(10);
Foo a[3]{1,2,3};

3.拷贝构造函数
class Foo{
         Foo(const Fool& other);
};
Foo a=10;
Foo a;
Foo b=a; //自身类型的引用
Foo b(a);
Foo b{a};


4.类型转换构造函数
class Foo{
         Foo(int x);
};
Foo a=10;

访问权限和继承方式

访问权限:4中访问权限,关键字有3种

默认访问权限:class是私有的,struct是公有的

  • 不可访问成员   冻结财产

  • 私有成员private            个人财产

  • 保护成员protected       家族财产

  • 公有成员public             公有财产

 继承方式对访问权限的影响:三种继承方式,关键字3个,和访问权限公用一套

  • 私有的和不可访问都是不可访问

  • 继承方式决定最高访问权限

  • 默认继承方式是私有的,最常用的继承方式都是公有继承

  • 成员变量一般都是保护成员(子类访问父类,父类设为家族财产)

空类 

class foo{
};
默认构造函数
默认拷贝构造函数:bit-by-bit
默认赋值运算符:bit-by-bit
默认析构函数
非静态成员函数,有一个默认的this指针。

常const

  • 修饰各种类型☞const char* p char const*p  char* const p

  • 常函数:修改类的成员函数

  • 常对象只能调用常函数

class Foo

{

    void F() const;  

};

    void Foo::F() const {}

静态static

  • 静态成员属于类

  • 静态成员变量:必须类外初始化,不需要再写static

  • 静态成员函数:静态成员函数没有this指针

  • 静态成员函数:不能访问非静态成员,只能使用静态成员

  • 两种调用方式,通过对象调用,通过类名调用

  • 没有对象,也可以调用静态成员函数

  • 静态成员函数 只能 调用静态成员(静态成员函数、静态成员变量)无this指针

  • 不能调用非静态成员(普通成员变量,普通成员函数)

  • 非静态成员可以调用静态成员?可以

友元friend 

  • 破坏封装性。一般,同一模块内部使用友元,模块内部开的后门。

  • 可以访问类的所有成员(只能❌全部、仅仅)

  • 不是成员函数,和访问权限无关。

  • 单向性、不能传递、不能继承。

class Foo{
private: 
         friend void Bar();//不是成员函数,只是声明。
};
互为友元函数
class A{
       friend class B
};
class B{
       friend class A
};

第三章

重载 

  • 运算符重载的本质是函数重载,函数名是operator运算符。
  • 重载:是为了代码间接,不是代码复用❌,不是所有运算符能被重载❌。
  • 一般都是成员函数,

  • 两种形式:成员函数重载,全局函数重载(往往被声明友元函数,不是必须是友元函数❌)

  • 输入输出运算符>> <<必须是全局函数重载,声明友元函数

  • friend ifstream& operator>>(ifstream& ifs,vertor<*Student>& all>);

  • friend iostream& operator<<(iostream& ios,const MyString& other);


  • = () [] ->只能被重载为成员函数

  • << >>只能被重载为全局函数,声明为友元函数

  • 前置++返回*this:是&

  • 后置++(int)返回是temp:不能是&

  • +重载,返回的是局部变量:不能是&

重载为成员函数

  • 左操作数必须是当前类型
  • 一元运算符不需要参数,当前对象是操作数。
  • 二元运算符只要一个参数,代表右操作数,当前对象是左操作数。
  • = () [] ->只能被重载为成员函数

类型转换运算符重载 

  • operator目标类型();
  • operator flaot();
  • static_cast<目标类型>(表达式);
  • explicit关键字,避免默认类型转换
operator float();
static_cast<float>(a);
explicit operator float();

函数运算符的重载

  • 函数指针
  • 仿函数
  • 内置仿函数
  • Lambda表达式
  • 自定义类型重载<运算符

第四章-子类父类 

  • 基类Base(父类)

  • 派生类Derived(子类):子类对象拥有父类的所有成员(但是构造和析构函数也独有)

  • C++支持多继承

  • UML的类图三格矩形,箭头☞表示继承(子类指向父类) 

  • 析构函数调用的顺序:基类☞成员对象☞派生类

  • 析构函数调用的顺序:派生类☞成员对象☞基类

class A{};//父类
class B:public A  //子类
{
   A a;          //成员对象
};


B b(a); //构造:A->a->B  析构:B->a->A
  • 子类对象给父类对象赋值✔
  • 父类对象给子类对象赋值❌
Base b;//父类
Derived d;//子类
d=b;//❌
b=d ;//父类指针指向子类对象
Base* pb = new Derived; 
Base& rb=d;    

第五章-virtual多态

  • virtual实现机制:虚函数表。(实现动态多态以牺牲性能为代价)
  • 重载调用机制:取决于不同参数列表

  • 隐藏调用机制:取决于变量类型

  • 覆盖调用机制:取决于对象类型(运行结果)

  • 如何调用被隐藏的父类的成员函数(通过Base::Fun,通过域操作符


  • 同名函数因为上下文不同会有不同的实现的一种机制

  • 静态多态:函数重载实现,在编译阶段完成

  • 需要花费更多编译时间,不会降低运行速度

  • 动态多态:继承+虚函数,运行阶段完成

  • 动态多态以牺牲性能(运行速度)为代价


  • 纯虚函数和抽象类

  • 纯虚函数:虚函数 函数体=0;//都有,但是方式不一样(2)

  • 定义了纯虚函数的类,叫做抽象类

  •  Java:只有纯虚函数的类,叫做接口interface

  • 抽象类不能实例化对象


  • RTTI运行时类型识别:(3)不同种类各自特有的
  • typeid()
  • dynamic_cast()
class Base {
public:
    void func() {
        std::cout << "Base::func()" << std::endl;
    }
};

class Derived : public Base {
public:
    void func() {
        std::cout << "Derived::func()" << std::endl;
    }
};

int main() {
    Derived d;
    d.Base::func(); // 调用基类的 func()
    d.func();       // 调用派生类的 func()
    return 0;
}
// 抽象基类
class Shape {
public:
    // 纯虚函数声明
    virtual void draw() const = 0;
 
    // 虚析构函数(推荐用于包含虚函数的类)
    virtual ~Shape() {}
};
//3.各自特有的
		if (typeid(*p) == typeid(Teacher))
		{
			//动态类型转化❗
			Teacher* pt = dynamic_cast<Teacher*>(p);
			pt->Xiaban();
		}
		else//if (typeid(*p) == typeid(Student))
		{
			Student* ps = dynamic_cast<Student*>(p);
			ps->Game();
		}

第六章-模板

  • 模板编程也叫做泛型编程
  • 目的:代码复用
  • 函数是为了代码复用,子类继承父类是为了代码复用,模板编程是为了代码复用
  • 函数模板,类模板:在指定类型后,变成了模板函数,模板类。
  • 函数模板 => 模板函数
  • 函数模板可以实例化成多个模板函数
  • 高级语言中,1个函数模板,经过编译以后,在二进制代码中,会有对各对应的模板函数。
  • template <typename T>(没有分号;)  
  • 函数类型 函数名(参数列表){函数体}
  • 在没有二义性的情况下,函数模板的类型参数可以省略。
  • 类模板=>类函数
  • 类模板不能隐式调用,函数模板可以
Template<typename T>
T add(T a, T b){return a+b;}	

add<int>(1,2);    add(1,2);
Add(1,2.3);  //二义性

第七章-STL

  • STL:Standard template library 标准模板库
  • 三大核心:容器、迭代器、算法
  • 六大组件: .................、适配器、仿函数、分配器
  • 常用容器的内部实现:
  • vector:动态数组
  • list:双向链表
  • map/set:红黑树(平衡树的一种,用于动态查找)

  • vector:push_back 和 pop_back和begin 和 end
  • 注意:end指向最后一个元素的下一个迭代器[  )是一个左闭右开区间

  • list:push_back和pop_back和push_front和pop_front
  • sort不能使用list

  • vector array deuqe随机访问迭代器
  • list不支持下标运算符sort不能使用
  • map支持,存在插入和修改两种功能

  • 会使用基于范围的for循环,对应的迭代器进行遍历
  • 基于范围的for循环
  • 使用迭代器进行遍历
  • for_each()遍历

  • 构造函数:可以调用无参构造函数
  • vector<int>vi
  • vector<int> vi(10);
  • vector<int> vi(99,10);
  • vector<int>vi(first,last);左闭右开的区间

  • //迭代器的定义:推到和自动定义
  • 定义迭代器的两种方式:常规和自动推导
  • vector<int>::iterator itr;
  • auto itr=vi.begin()  //自动推导必须初始化
  • map<int,int>m;

  • map<int,int>::iterator itr;

  • auto itr=map.begin();

算法:

  • 容器begin end实参
  • sort(first,last,二元谓词)形参
  • random_shuffle() 洗牌
  • generate_n(back_insetor(),n,[](){});向容器中插入n个元素
  • copy(,,ostream_iterator<int>(cout,间隔符));
  • accumulate(,,0) 累加和

第八章-文件IO

#include<fstream>

ifstream ifs(“data.txt”,ios::in); //文本文件 打开方式
While(!ifs.eof())ifs>>容器;
ifs.close();

//控制台的输出运算符的重载:常引用
//输入运算符的重载:引用
ifstream& operator>>(ifstream& in,容器的引用list<Student*>& all){
 .....;
return in;
}

第九章-异常

  • try catch throw干什么?
  • try catch:捕获和处理异常
  • throw:抛出异常 

子函数()
{  //若干层调用的子函数
    throw(某个类型的异常) //抛出异常
}
主函数
{
     try
{
  子函数的调用;
}
catch(类型1)
{
}
catch(类型2)
{
}
//取决于数据的类型

第十章❗

  • auto自动类型推导

  • 基于范围的for循环

  • Lambda表达式

面向对象的知识点

  • 父类指针指向子类对象

  • 唯一不变的是变换,以不变应万变。

  • 父类指针:抽象,稳定。

  • 子类对象:具体,变换。

  • 三大原则:封装变化点、针对接口进行编程,优先使用组合

  • is-a:继承和派生-代码复用

  • has-a:成员对象-代码复用

  • 设计模式的来源是建筑设计领域

SOLID五大原则

  • SRP单一职责原则。

  • OCP开闭原则:对扩展开放,对修改关闭。(增加策略业务逻辑,❌1.增加分支(其实是修改函数,都在一个函数体)2.增加规则-增加类)

  • LSP里氏替换原则。

  • ISP接口隔离原则。

  • DIP依赖倒置原则:高层模块不依赖于底层模块,二者应该依赖于抽象。(高层-抽象类父类-子类_底层模块)


  • 代码复用:函数、继承、组合、模板

  • 使用代码简洁的语法:重载(函数重载,运算符重载),默认参数

  • 实现面向对象:继承、虚函数、父类指针指向子类对象

  • inline内联函数:小函数、没有循环

  • Set/Get基本是内联函数

栈里的对象-调用2次构造函数 2次析构函数
class Foo
{
};

main()
{
       Foo* pd=new Foo;//pd在栈里面Foo类型指针,new一个Foo类型的变量堆里面
       delete pd;
       Foo d1; //局部变量,对象在栈里面
}
//释放栈,释放栈里的对象,调用对象的析构
void fun(){
****************
}

inline void fun(){
****************
}//不是函数调用,直接嵌入函数体中了

main()//main函数体积变大了,以牺牲体积,提高运行速度
{
       #########
       fun();
       #####
       fun();
}
  • 单选:30
  • 多选:10
  • 判断:10
  • 填空:20
  • 大题:40

http://www.kler.cn/a/463442.html

相关文章:

  • C++访问数据库
  • DDoS攻击防御方案大全
  • leetcode 173.二叉搜索树迭代器栈绝妙思路
  • Leetcode打卡:我的日程安排表II
  • 【Vue3】h、ref:vue3的两个新特性(重要)-h和ref
  • 整合版canal ha搭建--基于1.1.4版本
  • vite+vue3项目启动报错
  • windows C#-声明、实例化和使用委托
  • 青少年编程与数学 02-005 移动Web编程基础 10课题、设备调用
  • 创建线程的8种方法
  • 计算机网络原理(谢希仁第八版)第4章课后习题答案
  • 在 Swift 中使用 SQL 组合人员和地址数据
  • ChatGPT 与 AGI:人工智能的当下与未来走向全解析
  • UE5材质节点Frac/Fmod
  • NestJS 中间件与拦截器:请求处理流程详解
  • 前端安全措施:接口签名、RSA加密、反调试、反反调试、CAPTCHA验证
  • Go 语言 API 限流实战:保障系统稳定性的护盾
  • 2024年终总结:非常充实的一年
  • Three.js教程007:响应式画布与全屏控制
  • 深度学习每周学习总结R2(RNN-天气预测)
  • Postman[5] 环境变量和全局变量
  • 虚拟机Centos下安装Mysql完整过程(图文详解)
  • 快速掌握Elasticsearch检索之二:滚动查询(scrool)获取全量数据(golang)
  • Dockerfile 构建继承父镜像的 ENTRYPOINT 和 CMD
  • Python性能分析深度解析:从`cProfile`到`line_profiler`的优化之路
  • 数据结构:排序