委托构造函数
//构造函数可以在同一个类中一个构造函数调用另一个构造函数,从而达到简化代码的目的:
//例调用之前的myclass如实现初始化myclass
class Myclass {
private:
int num;
public:
Myclass(int n):num(n){}
Myclass():Myclass(0){}
};
类的初始化
class Myclass {
private:
int num;
public:
Myclass(int n):num(n){}
Myclass():Myclass(0){}
};
//类内初始化,将变量的初始化和变量定义写在一起
新空指针
//nullptr空指针新写法 Null是旧写法
int* ptr = nullptr;
新枚举类
//新枚举类,类名前+class,成为强类型可以避免命名冲突
enum class MyEnum{one,two,three};
enum class MyEnum2{one, two, three};
int main{
MyEnum a = MyEnum::one;
return 0;
}
智能指针
unique_ptr :不允许多个指针共享资源,可以用标准库中的move函数转移指针
shared_ptr :多个指针共享资源
weak_ptr :可复制shared_ptr,但其构造或者释放对资源不产生影响
这里介绍介绍常用的unique_ptr。
//智能指针make_unique,推荐使用make_unique避免构造对象出现野指针
struct SomeData {
int a, b, c;
};
void f() {
//SomeDatak data=new SomeData;
// unique_ptr<SomeData> data( new SomeData);
auto data = make_unique<SomeData>();
auto obj = make_unique<SomeData>();
data->a = 1;
data->b = 2;
obj->c = 5;
}
初始化列表
//初始化列表 (Initializer List)
vector<int> myvec = { 1,2,3 };
vector<double> myvec2 = { 1.2,2.5,3.7 };
vector<set<int>> v = {};//支持嵌套
for的遍历
//for对STL容器的遍历
for (int x : myvec) {
cout << x << endl;
}
//基于范围的 for 循环
//结构化绑定
map<int,string> mymap= {{ 1,"one" }, { 2,"two" },{ 3,"two" } };
for (auto& s : mymap) {
std::cout << s.first << ':' << s.second << ' ';
}
//old style
for (map<int, string>::iterator it = numMap.begin(); it != numMap.end();
++it) {
cout << it->first << "->" << it->second << endl;
}
类型推导auto
//auto关键字,类型推导
auto name = "张家辉";
auto b = 1.4f;
template<typename T,typename U>
auto add(T x,U y){return x+y}//自动推导返回值类型
constexpr
//constexpr将运行时的计算提前到编译时来做性能优化,可以修饰变量和函数
constexpr int pow(int x) { return x; }
int pow2(int x) { return x; }
int a[pow(5)];//int a[pow2(2)];没有constexpr,这样不行
lambda表达式
[捕获列表](参数列表) mutable(可选) 异常属性 -> 返回类型 {
// 函数体
}
例如输出一个表达式的返回值
cout<<[](int x, int y) {return x + y; }(2, 5);
定义一个泛型变量,并传参
auto sum= [](int x, int y) {return x + y; };
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
- override关键字作用:
如果派生类在虚函数声明时使用了override描述符,那么该函数必须重载其基类中的同名函数,否则代码将无法通过编译。 - 举例子说明:
结论 :struct Base
{
virtual void Turing() = 0;
virtual void Dijkstra() = 0;
virtual void VNeumann(int g) = 0;
virtual void DKnuth() const;
void Print();
};
struct DerivedMid: public Base
{
// void VNeumann(double g);
//接口被隔离了,曾想多一个版本的VNeumann函数
};
struct DerivedTop : public DerivedMid
{
void Turing() override;
void Dikjstra() override; //无法通过编译,拼写错误,并非重载
void VNeumann(double g) override; //无法通过编译,参数不一致,并非重载
void DKnuth() override; //无法通过编译,常量性不一致,并非重载
void Print() override; //无法通过编译,非虚函数重载
};
如果派生类里面是像重载虚函数 就加上关键字override ,这样编译器可以辅助检查是不是正确重载,如果没加这个关键字 也没什么严重的error, 只是少了编译器检查的安全性