一、空指针
NULL
nullptr
#define NULL 0
typedef decltype(nullptr) nullptr_t;
c语言中
#define NULL (void*)0 代码空指针和0双重身份
c++中
#define NULL 0 仅代表0
指针用nullptr
nullptr是nullptr_t类型的常量对象,可隐式转换为任何类型的指针及比较,但不能转换成非指针类型,比如int
二、列表初始化
int x{};
double y{2.73};
string str{"abc"};
int a[] = {1,2,3};
vector<int> v = {1,2,3};
三、新式循环
基于范围的循环,是一种语法糖,本质上使用迭代器来实现,循环时不能变动容器,也不能增加容器元素,否则导致遍历迭代器失效,发生未知错误
vector<int> v;
for (auto & e:v)
{
cout<<e<<endl;
}
四、新式函数声明
auto func(int x)->decltype(x)
{
return x*x;
}
五、default
显式指定构造函数析构函数等成员函数使用编译器缺省实现
使用default后,并不影响其他构造函数的重载和实现
class default_demo{
public:
default_demo()=default;
~default_demo()=default;
default_demo(const default_demo &)=default;
default_demo & operator=(const default_demo &)=default;
default_demo(const default_demo &&)=default;
default_demo & operator=(const default_demo &&)=default;
default_demo(int){}
};
六、delete
显式禁用某些函数,通常是类的构造函数和拷贝构造函数,以阻止对象拷贝
不仅可用于类的成员函数,也可用于普通函数,以禁止 某些形式的重载
class default_demo{
public:
default_demo()=default;
~default_demo()=default;
default_demo(const default_demo &)=delete;
default_demo & operator=(const default_demo &)=delete;
};
default_demo d1;
default_demo d2 = d1; //无法赋值拷贝,编译错误
七、override
显式标记虚函数重载,派生类成员函数使用override修饰,那么它一定是虚函数,而且签名必须与基类声明一致,否则会报错
struct base{
virtual ~base() = default;
virtual void f() = 0;
virtual void g() const{};
void h(){}
};
struct derived{
virtual ~derived() = default;
void f() override{};
void g() const override{};
void h(){}
};
八、final
final用在类名后,显式禁止类被继承,即不能有派生类
final用在函数后,显式禁止该函数被派生类重载
struct interface{
virtual void f() = 0;
virtual void g() = 0;
};
struct abstract :public interface{
virtual void f() override final{};
virtual void g() override {};
};
struct last final:public abstract {
virtual void f() override {}; //错误使用final不能被重载
virtual void g() override {}; //可以被重载
};
struct error :public last
{};//错误last 使用了final不能被继承
九、成员函数初始化
c++11/14允许类在声明的时候,使用赋值或者花括号 的方式初始化成员变量,无需在构造函数中特别指定,但是静态成员不行,只能在类外初始化,这种形式也不能用auto来推导变量类型。
class demo{
public:
int i = 0;
string s = "hello";
vector<int> = v{1,2,3};
};
十、委托构造
委托构造函数,无需写一个特殊初始化函数,来初始化成员变量,而是可以直接调用本类其他构造函数,把构造工作委托给其他构造函数完成。
class demo{
public:
demo():demo(0, 0){}
demo(int a):demo(a, 0){}
demo(int a, int b)
{x=a;y=b}
private:
int x;
int y;
};