C++笔记
将数字以十六进制输出:cout<<hex<<100<<endl;
将数字以八进制输出:cout<<oct<<100<<endl;
精度控制
include
保存a位小数:setprecision(a)
将b保留a位:cout<<setprecision(a)<<b<<endl
将b保留小数点后a位:cout<<setiosflags(ios::fixed)<<setprecision(a)<<b
const限定符:限制局部变量为常量
ae+N:a*10n
ae-N:a*10-n
名称空间:控制名称作用域
程序中创建不同名称空间
- 声明区域:可以在区域中进行声明
- 潜在作用域:从变量声明点开始,到声明区域
使用空间名名称
-
除了用户定义的名称空间,还有全局文件名称空间
-
名称空间可嵌套使用,开放且可以随时添加新内容<如果同名做合并操作>
-
名称空间可以匿名隐式加上static
-
可以起别名:A=B
-
匿名的名称空间可直接访问
构造函数:程序声明对象是否可自动调用
-
数据成员名中使用m_前缀或成员名中使用后缀_
-
public:一个类的构造函数名和类名相同
-
引用:&别名=原名 两个名称共享内存空间
-
引用一旦初始化就无法更改,引用作函数传参:形参修饰实参
-
简化实参:值、地址、引用
-
本质是常量指针const
-
如果函数声明有默认实参,那么函数定义则不用加(一个就行)
-
现阶段函数占位意义不大
函数重载细节
- 引用作为条件
- 碰到默认参数(报错)
类中属性、行为统一叫成员
成员属性、成员变量、成员方法
权限 | 类内 | 类外 | 继承性 |
---|---|---|---|
public(公共权限) | 可访问 | 可访问 | 可继承 |
protected(保护权限) | 可访问 | 不可访问 | 可继承 |
private(私有权限) | 可访问 | 不可访问 | 不可继承 |
类外想要访问私有/保护权限对象,只能通过公共权限提供接口
class默认权限私有
struct默认权限公共
初始化列表方式
-
fun(int a,int b):A(a),B(b)
-
类对象作为类成员
-
隐式转换法
-
类内static:共享内存
静态成员对象两种访问方式
-
通过对象访问 对象.成员
-
通过类名访问 类名::成员
-
静态成员变量有访问权限
-
直接在类里面定义的变量为私有变量
构造函数:类名(){}
无返回值且无void
与类名相同
可以有参数且发生重载
- 调用对象时自动调用构造
析构函数:~类名(){}
- 创建类时调用构造函数,类注销时调用析构函数
- 拷贝构造函数,默认构造调用不用加括号
- 浅拷贝:拷贝指针
- 深拷贝:拷贝数据
- 静态成员函数(有访问权限的),所有对象共享同一个函数(内存空间),只能访问静态成员变量
- 不可以访问非静态成员变量
对象模型和this指针:成员变量和成员函数分开存储
-
空对象占用内存空间1B,为了区分空对象位置
-
每个空对象有独一无二地址
-
this指针是隐含每一个非静态城公园函数内的指针
用途:
-
解决名称冲突
-
返回对象自身
-
指向被调用成员函数所属对象
-
this指向p2的指针,*this指向p2本体
常函数:
-
成员函数后加const
-
不可修改成员属性
-
加关键字mutable,常函数依然可修改
-
成员后加congst,修饰this指向
类内声明:friend void fun(c)
-
这样fun可访问c的私有成员,不用特地使用public声明
-
类外创建类内成员函数
-
类名::成员函数(){}
运算符重载
type operator+(type &A){}
-
成员函数重载(可链式嵌套)
-
全局函数重载
type operator+(type &A1,type &A2){}
-
给运算符新的定义,赋予其另一种功能
-
适应不同数据类型
-
对于内置数据类型不可重载
-
不要滥用运算符重载
左移运算符重载<<
-
operator<<()
-
全局函数重载左移运算符(只能在全局中)
-
ostream operator<<(ostream &cout,type &A){}
递增运算符重载++
-
operator++()前置重载
-
operator++(int)后置重载
-
记录结果
-
后递增
-
返回
-
总之,重载一定会用到operator
赋值运算符重载
关系运算符重载
函数调用符重载()
-
仿函数:重载起来像函数被调用
-
继承:下级别成员拥有上级别的共性
减少代码重复
class A:public B{}
- A继承B中所有内容
class 子类:继承方式 父类{}
public、protected、private
-
A:元素+方法(多种)
-
B:元素+方法(单种)
继承中对象模型
-
父类中所有非静态成员都会被子类继承
-
继承构造和析构顺序
-
先构造父类,后子类
-
先析构子类,后父类
-
继承同名成员处理方式
-
通过子类对象访问继承成员,应加作用域 父类::子成员
-
直接调用的是子类成员
-
子类成员会隐藏父类中继承下来的方式
-
同名静态成员继承:对象.类名访问
-
多继承:class子类:方式 父类1,方式 父类2
菱形继承:二义性处理
虚继承(继承指针)
-
多态:静态多态:函数/运算符重载
-
动态多态:派生类和函数运行时多态
满足条件:
继承关系
子类重写父类虚函数
重写:函数返回值类型、函数名、参数列表相同
动态多态使用:子类重写父类虚函数
父类引用接受子类对象可行,允许父子类型转换。而要让父类使用子类的方法,则将父类定义为虚函数就行。
引用时晚绑定则可避免引用时父类指向子类问题。
引用类型取决于等号右边
原理剖析
vfptr:virtual function pointer
- 虚函数指针表
vftable:虚函数表(记录虚函数地址)
-
当子类重写父类虚函数,子类虚函数表内部会替换为子类虚函数地址
-
当父类指针或引用指向子类对象,发生多态
开闭原则:扩展开放,修改关闭
-
计算器基类:抽象
-
高内聚,低耦合
纯虚函数:
-
父类中虚函数无实际意义
-
重点在于子类中重写的功能
-
当类中有了纯虚函数,这个类也称抽象类
-
抽象类无法实例化对象,因此抽象子类必须重写父类,否则无法实例化对象
-
虚函数代码毫无意义,作用在于子类重写
-
用父类指针接收不同的子类
-
而多态给函数提供扩展性(传入指针)
虚析构/纯虚析构
-
父类对象无法析构子类对象,从而导致内存泄漏。虚析构解决此类问题
-
virtual ~fun()=0
-
纯虚析构函数应当有具体实现
-
而调用子类时使用指针
文件操作
-
ofstream:写操作
-
ifstream:读操作
-
fstream:读写
创建流对象:
-
ofstream ofs;
-
ofs.open()
-
ofs<<数据;
-
ofs.close()
打开方式:
-
ios::
-
in读
-
out写
-
ate文件尾
-
app追加
-
trunc删除创建
-
binary二进制
读写步骤相似
-
ifs.getline()行读
-
ifs.get()一个个读
模板
泛型编程
函数模板\类模板
template
声明一个模板,以至于后面不报错
类型不同,其它一样,则可用模板
template
-
自动类型推导,显示指定类型
-
函数模板注意事项
-
自动类型推导,必须推导出一致数据类型T才可使用
-
模板必须确定T数据类型才能使用
typename/类模板
-
显式指定类型发生隐式类型转换
-
普通函数和函数模板调用规则
-
如果函数模板和普通函数都可调,优先使用普通函数
-
可使用空模板参数列表强制使用函数模板
-
函数模板可发生重载
-
如果函数模板可产生更好匹配,优先调用函数模板
-
如果函数模板产生更好匹配,优先调用函数模板
局限性
-
并非万能,特殊数据类型需要特殊自定义数据类型实现具体化代码,优先调用具体化
-
template<>fun(typename &A)
-
故不用运算符重载也能实现
类模板
-
template<class A,class B>
-
无自动类型推导功能,可以有默认参数
-
类模板可以有默认参数
-
类模板对象作函数参数
typeid(A).name()
类模板与继承
子类继承的父类式一个类模板
需要指定父类中T的类型,如果不指定,编译器无法给子类分配内存
如果想灵活指定父类中T类型,子类也需要变类模板
如果父类是类模板,子类需要指定出父类中T的数据类型
类模板成员函数类外实现
template<class T1,class T2>
class P{}
template <class T1,class T2>
P<T1,T2>:
标签:容器,函数,子类,笔记,C++,重载,父类,模板 From: https://www.cnblogs.com/shuai-yi-zhou/p/17652764.html