c++ ignore

  • 同class 的 obj 互为friend
  • 传参和返回尽量引用
    • 返回时如果是临时变量不能引用
      • 加减乘除负号不能返回引用,正号可以
    • 传递者(return, 实参) 无需知道 接受者(函数返回类型,形参)是不是接受的引用
  • 尽量const(类方法,传参等)
  • 构造函数尽量初始化赋值不要通过{}赋值
  • c3+=c2+=c1 从右往左, operator += 如果返回值不是对象或其引用则不能连续
  • 操作符都是作用于左边

T pc = new T(a) 的操作

  • void* mem = operator new(sizeof(T))(实际内部调用malloc(n))
  • pc = static_cast(mem);//转型
  • pc->T:T(a) //调用构造函数(定义成员,赋值)

delete pc 的操作

  • T::~T(pc) //析构函数
  • operator delete(pc) //(实际内部调用free(pc)

new []要和 delete []对应用

  • 内存分配会16字节的倍数 (32位和64位都是?)
  • 如果没有对应,比如T *p = new T[3]; delete p
    • 调用delete p 会释放申请的动态内存,但是只会调用一次析构函数(图是有问题的应该是从下往上析构)
    • 调用delete[] p 才会在释放动态内存后,正确的调用三次析构函数
  • 如上图,如果不是new的数组,会少了从上往下的第二个3内存
    • 内存依次记录的是(16进制):
      • 分配的内存大小+1(1代表分配出去的意思,因为分配的大小会是16的倍数,可以用这一位)
      • 如果是数组会记录数组的大小
      • 实际数据
      • 同第一个
class Account
{
    public:
        static double m_rate; // 声明,同时需要在外部定义(应该是编译器怕导致重复链接 )
        static const int x = 2.1; // 常量可以,也可以用非常量的方式,但是不能在内外都赋予初始值
        static constexpr double d = 1.0; // 编译器-O0时对于非int char等需要这么操作
        static Account ac;    //可以不在外部定义(在外部定义也OK)
        Account ac;         // 错误类类型成员只能是static
};

double Account::m_rate;         //定义(必须要有这一步)
复制代码
  • 模板导致代码膨胀
  • 继承函数继承的是调用权
  • 委托模式共用引用修改时可以 copy-on-write (string的实现也是cow)
  • 成员函数同时存在const 和 non-const版本时,const obj 只能调用const的,non-const的只能调用non-const的
  • 继承和组合构造从内而外,析构由外而内,继承的父类析构必须是virtual
    • 继承空心三角箭头头
    • 组合实心菱形箭头尾
    • 委托空心菱形箭头尾
  • T转换函数 ex:operator double() const {return xxx;} 把T->double
  • 同时可以使用no-explict的构造函数 ex:T(double x){} double->T
Fraction f(3,5);
double d = 4.0+f; // 会先找operator(double, Fration),看看能不能把Fraction转换成double, 找 operator double()或者non-explict构造函数,但是共存可能会导致二义性
复制代码

pointer-like class

  • 特殊的重载符号 operator ->,重载后不会消耗掉->;
  • 迭代器也是一种智能指针

function-like class

  • 重载operator ()
  • 如果类型是依赖于模板参数的限定名,那么在它之前必须加typename,避免编译器在实例化时才知道,explain(T::c不加的话并不知道这个是个嵌套类型还是静态成员或者静态函数) 比如:
template <class T>
void foo() {
    T::iterator * iter; // 不加typename, 这一行可能是个乘法运算可能是个定义语句 
    // ...
}
复制代码

链接器相关: 我们需要注意从库中导入文件的粒度问题:如果某个特定符号的定义是必须的,那么包含该符号定义的整个目标文件(一个库可能会有多个目标文件)都要被导入

有默认值的会编译不通过(list模板参数有默认值)

虚函数实例内存多一个虚指针的大小

你可能感兴趣的:(c++ ignore)