OOP

stackedit 笔记待迁移

下标运算符

img
Fee(const fi& ){ }//
Fee a = fee;调用的是拷贝构造函数
b = fee;调用的是赋值运算符 如果 fee类型是fi 则会调用转换构造函数(上面第二行)
赋值运算符:传回一个左值以实现链式赋值(小心空间分配而与指针赋值)
记住:赋值运算符传回一个左值 返回的是对象的引用(不要返回this而要*this)
拷贝构造和赋值运算符 面对动态分配空间时 前者直接一段新空间 后者先销毁后分配 如果不想这么干 直接设为私有或者=delete
functor :
重载函数引用运算符img
数据类型转换:
单参构造函数转换
运算符转换
img
先把abc转换成xyz之后同等赋值
避免这样的自动隐式转换? 在有参数的构造函数中加一个explicit关键字
img

type conversion confusion:

A使用constructor 把B转换成A
B中可以用强制类型转换把自己转换成A
某个函数使用形参是B,实参是A,那么不知道如何转换!报错!
建议改换格式!
img
static_cast<>():
img
子类一般可以通过这个方式转换成父类const 不能转换走!
但是被转换后的子类 无法做自动检查 可能在父类中访问子类的内容导致未定义 此时建议用dynamic_cast<>()
img
例子: const int b = 9;int* q = const_cast(&b);*q = 2;实际上可以改也的确改了 但是没有用处,因为const 是在编译阶段直接替换成了一个实际值
建议参考 10_example_code_2024
is.setstate(std::ios::failbit); 对当前的cin报错 即cin的failbit状态设为true 转换为bool时为false
std::cin.ignore(std::numeric_limitsstd::streamsize::max(), '\n'); 若前一次输入只读到\n 则需要加上这一行把还在缓冲区里面的内容清除掉(一般都是cin.get(xxx)要搭配这个)
输出流重载 传入两个参数 对流一般都是常引用
cout.flush() 强制清空缓冲区 也就是直接输出 但是建议用cerr
针对一次输入输出流的manipulators 自定义

模版 :key idea 参数化类型名(函数模版类型有时不用明确传入) 严格要求隐式转换不允许!
重载函数优先!(重载函数可以用隐式转换)
类模版 定义类的时候就传入类中的类型参数
非类参数 : 不能用变量做模板参数!必须是实际值 const可以吗?

模版类的继承 可以继承模版类给下一个模版类 也可以继承模版类给非模版类(给参数就行)

 template <class T>
 class base{}
 class Derived: public base<Derived>{}

以上是CRTP: Curiously recurring template pattern 有什么用?
继承类可以调用自己的函数来实现多态 而不需要virtual函数
模版中的友元 有三种友元函数

  1. 什么都不管正常友元(当然可以在类外面定义)
  2. 加入类型改成模版类型:约束模版友元函数 (这个东西只能定义在类内!!!)(调到外面编译器就不知道T是原来的T还是一个比较新的T)
  3. 使用新的模版参数 也就是再用一次template 此时,是非约束模版友元函数 也就是说这个友元函数可以接受任意类型(也可以在类外面定义)
    模版里面的static 静态成员变量?
Myclass<int > 
int Myclass<int > static int shared_data;
Myclass<double>
double Myclass<double> static double shared_data;

这叫BUG?不!叫特性!(笑)
此时创建另一个Myclass可以使用的静态成员变量就是int类型的
相当于同类型类的构成一个小团体共用其中的静态成员变量 其他类型的不可见!

迭代器 iterator

review:允许访问容器中的元素 但是不暴露容器的内部实现
img
像指针的功能 :
如何实现? 关键部分: 自加 解引用 是否相等
img
C++模板的特化(specialization)和偏特化(partial specialization)
hwojul的笔记.lec13

异常

  1. 抛出异常:throw(exception_object) 之后回到caller中
  2. 捕获异常:catch(exception_object) 如果捕获到异常,则执行catch块,否则执行throw之后的语句 如果有异常但是不去捕获,那么程序就结束了 如果捕获的类型和所有catch的类型都不匹配那么继续抛出
  3. catch(...) 捕获所有异常
  4. try { } catch(...) { }才能捕获到异常!!可以加多个catch碰到第一个捕获就停止
  5. 尽量不要把catch(...)放在最前面
  6. noexcept : 告诉编译器函数不会抛出异常 可能起到优化的作用
  7. unexpected exception 已经定义了noexcept不会抛出异常 但是如果实际上抛出 那就报unexpected exception(或者告诉编译器的异常不一样)
  8. 出现异常之后一般会进行栈展开 也就是析构 释放资源 但是如果如果析构函数中抛出异常 1. 把可能出现的错误都放到其他的函数里面 2. 直接写异常 不管了 3.用智能指针 在析构的时候自动释放资源 ()
  9. 析构的时候发生了异常?不能throw! 否则直接退出程序。
  10. 处理异常 使用引用来捕获! 指针?可能会忘掉释放资源! 实例?可能发生子类和父类转换的问题!

降低耦合:

10.06

高内聚:

智能指针

unique_ptr:
share_ptr: 多个指针引用一个对象时 若要释放对象,必须等待所有指针都释放之后 否则会报错 key idea:引用计数
weak_ptr: 可以出现对象销毁时指针置零 也即指向的对象可以被直接销毁 并不增加引用计

posted @ 2024-11-27 09:32  My_Dearest  阅读(42)  评论(0)    收藏  举报