委托构造函数

  1. //构造函数可以在同一个类中一个构造函数调用另一个构造函数,从而达到简化代码的目的:
  2. //例调用之前的myclass如实现初始化myclass
  3. class Myclass {
  4. private:
  5. int num;
  6. public:
  7. Myclass(int n):num(n){}
  8. Myclass():Myclass(0){}
  9. };

类的初始化

  1. class Myclass {
  2. private:
  3. int num;
  4. public:
  5. Myclass(int n):num(n){}
  6. Myclass():Myclass(0){}
  7. };
  8. //类内初始化,将变量的初始化和变量定义写在一起

新空指针

  1. //nullptr空指针新写法 Null是旧写法
  2. int* ptr = nullptr;

新枚举类

  1. //新枚举类,类名前+class,成为强类型可以避免命名冲突
  2. enum class MyEnum{one,two,three};
  3. enum class MyEnum2{one, two, three};
  4. int main{
  5. MyEnum a = MyEnum::one;
  6. return 0;
  7. }

智能指针

unique_ptr :不允许多个指针共享资源,可以用标准库中的move函数转移指针
shared_ptr :多个指针共享资源
weak_ptr :可复制shared_ptr,但其构造或者释放对资源不产生影响
这里介绍介绍常用的unique_ptr。

  1. //智能指针make_unique,推荐使用make_unique避免构造对象出现野指针
  2. struct SomeData {
  3. int a, b, c;
  4. };
  5. void f() {
  6. //SomeDatak data=new SomeData;
  7. // unique_ptr<SomeData> data( new SomeData);
  8. auto data = make_unique<SomeData>();
  9. auto obj = make_unique<SomeData>();
  10. data->a = 1;
  11. data->b = 2;
  12. obj->c = 5;
  13. }

初始化列表

  1. //初始化列表 (Initializer List)
  2. vector<int> myvec = { 1,2,3 };
  3. vector<double> myvec2 = { 1.2,2.5,3.7 };
  4. vector<set<int>> v = {};//支持嵌套

for的遍历

  1. //for对STL容器的遍历
  2. for (int x : myvec) {
  3. cout << x << endl;
  4. }
  5. //基于范围的 for 循环
  6. //结构化绑定
  7. map<int,string> mymap= {{ 1,"one" }, { 2,"two" },{ 3,"two" } };
  8. for (auto& s : mymap) {
  9. std::cout << s.first << ':' << s.second << ' ';
  10. }
  11. //old style
  12. for (map<int, string>::iterator it = numMap.begin(); it != numMap.end();
  13. ++it) {
  14. cout << it->first << "->" << it->second << endl;
  15. }

类型推导auto

  1. //auto关键字,类型推导
  2. auto name = "张家辉";
  3. auto b = 1.4f;
  4. template<typename T,typename U>
  5. auto add(T x,U y){return x+y}//自动推导返回值类型

constexpr

  1. //constexpr将运行时的计算提前到编译时来做性能优化,可以修饰变量和函数
  2. constexpr int pow(int x) { return x; }
  3. int pow2(int x) { return x; }
  4. int a[pow(5)];//int a[pow2(2)];没有constexpr,这样不行

lambda表达式

  1. [捕获列表](参数列表) mutable(可选) 异常属性 -> 返回类型 {
  2. // 函数体
  3. }

例如输出一个表达式的返回值

  1. cout<<[](int x, int y) {return x + y; }(2, 5);

定义一个泛型变量,并传参

  1. auto sum= [](int x, int y) {return x + y; };
  2. cout<<sum(1, 2);

lambda表达式参考:https://changkun.de/modern-cpp/zh-cn/03-runtime/#3-1-Lambda-%E8%A1%A8%E8%BE%BE%E5%BC%8F

OVERRIDE

  1. override关键字作用:
    如果派生类在虚函数声明时使用了override描述符,那么该函数必须重载其基类中的同名函数,否则代码将无法通过编译。
  2. 举例子说明:
    1. struct Base
    2. {
    3. virtual void Turing() = 0;
    4. virtual void Dijkstra() = 0;
    5. virtual void VNeumann(int g) = 0;
    6. virtual void DKnuth() const;
    7. void Print();
    8. };
    9. struct DerivedMid: public Base
    10. {
    11. // void VNeumann(double g);
    12. //接口被隔离了,曾想多一个版本的VNeumann函数
    13. };
    14. struct DerivedTop : public DerivedMid
    15. {
    16. void Turing() override;
    17. void Dikjstra() override; //无法通过编译,拼写错误,并非重载
    18. void VNeumann(double g) override; //无法通过编译,参数不一致,并非重载
    19. void DKnuth() override; //无法通过编译,常量性不一致,并非重载
    20. void Print() override; //无法通过编译,非虚函数重载
    21. };
    结论 :
    如果派生类里面是像重载虚函数 就加上关键字override ,这样编译器可以辅助检查是不是正确重载,如果没加这个关键字 也没什么严重的error, 只是少了编译器检查的安全性