基础

三大特性

  • 封装
    以class为基础单元,将属性和方法捆绑,对外部隐藏内部细节,通过访问修饰符来控制权限:private、protected、public
    • private
      只能对当前类起作用,不能被子类访问,外部无法访问
    • protected
      可以被子类访问,但是外部无法访问
    • public
      可以被内部外部随意访问
  • 继承
    class默认是按照private继承,struct是按照public继承
    • private继承
      子类继承后所有非私有方法成员(除构造、析构、重载、友元)都变成了私有
    • protected继承
      子类继承后所有非私有方法成员都变成了保护
    • public继承
      子类继承后所有非私有方法成员都保持原来的权限
  • 多态
    编程中同一个接口或者操作在处境不同的情况下有不同的行为
    • 编译时多态
      1. 函数重载
        1
        2
        int add(int a, int b) { return a + b; }
        float add(float a, float b) { return a + b; }

        在C中无法进行重载哦,因为C的函数名在目标文件(.o)中的符号名就是原函数名,而cpp会有name mangling机制,将add函数的符号编码成函数名+参数类型,例如addiaddfaddd

      2. 运算符重载
      3. 模板
        模板函数可以接受不同类型的输入
    • 运行时多态
      1. 虚函数
        通过基类的指针或者引用在运行时自动调用实际对象所属的派生类的函数版本,达到一个接口多种实现的功能,
      2. 继承

继承

多态

部分特殊语法

final

当类或者函数后加上final,则表明该类或者该函数不能被继承或者重载

  • 增强代码可读性,更加明确表明代码含义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Base final {
public:
virtual void foo() final {
// 一些操作
}

virtual void bar() {
// 一些操作
}
};

class Derived : public Base { // 编译错误:Base 类不能被继承
public:
void foo() override { // 编译错误:foo 函数不能被重写
// 一些操作
}

void bar() override {
// 一些操作
}
};

左值、右值、引用

  • 左值: 变量,可以取地址
  • 右值: 临时的对象,无法取地址, 10,std::string(“tmp”), func()// 如果func()返回非引用,则返回值是右值
  • 右值引用:
    • 使用&&来表示,只能绑定到右值,为了支持移动语义和完美转发
    • 移动语义:允许将资源从一个对象转移到另一个对象,而不需要进行复制
      1
      2
      MyString str1("Hello");
      MyString str2 = std::move(str1);
你想表达 应该写 值类别
持久对象,可修改 T& 左值引用
持久对象,只读 const T& 万能引用(可绑右值)
临时对象,资源可偷 T&& 右值引用
转发任意值(模板) T&& + std::forward 万能引用
强制转为可移动状态 std::move(x) 产生 xvalue

push_back && emplace_back

特性 push_back emplace_back
参数 对象本身或隐式可转换 构造函数的参数包
构造位置 栈上临时对象,再移入 直接在 vector 内存构造
临时对象 有(除非传右值)
适用场景 已有对象,强调类型安全 新构造对象,性能敏感