C++ 11
nullptr
nullptr 是用于解决 NULL 和 0 的有疑义关系的。NULL 通常被义为(void*)0。在
如下应用中会引发歧义。
#include <iostream>
using namespace std;
void f(int){}
void f(bool){}
void f(void*){}
int main()
{
f(0);// calls f(int), not f(void*)
f(NULL);// might not compile, but typically calls f(int). Never calls f(void*)
f(nullptr); // calls f(void*) overload
}
1) C++ 视 0 首先为 int 型,因此,调用 f(0) 即调用 f(int)
2) NULL 的情况复杂些,C++ 首先视其为广义整型。假如 NULL 被定义为普通
的 0,则调用 f(int);
如果 NULL 被定义成 0L,则 long -> int, long -> bool, 0L -> void*, 这三
种情况都是合法的,此时,编译器会报错
3) 使用 nullptr,则不会有重载函数调用模糊的问题
- nullptr 不属于广义整型,也不是普通意义上的指针。
- nullptr 的实际类型是 std::nullptr_t,它能够隐式的转换成所有的原始指针
类型,故可将其视为一个可指向所有类型的指针。
final
关键字 final 有两个用途。第一,它阻止了从类继承;第二,阻止一个虚函数的覆写。
阻止了类的无限扩展。
class A
//final
{
public:
virtual void func() const;
};
class B: A
{
public:
void func() const override final; //OK
};
class C: B
{
public:
void func()const; //error, B::func is final
};
=default =delete
default
C++ 的类有四类特殊成员函数,它们分别是:默认构造函数、析构函数、拷贝构
造函数以及拷贝赋值运算符。
这些类的特殊成员函数负责创建、初始化、销毁,或者拷贝类的对象。
如果程序员没有显式地为一个类定义某个特殊成员函数,而又需要用到该特殊成员
函数时,则编译器会隐式的为这个类生成一个默认的特殊成员函数。
#include <iostream>
using namespace std;
class A
{
public:
A() = default;
~A() = default;
A(const A& other) = default;
A& operator=(const A& other) = default;
A(int x ):_x(x){}
private:
int _x;
};
int main()
{
A a;
return 0;
}
delete
为 了 能够显式的禁用某个函数,C++11 标准引入了一个新特性 :
"=delete"函数。只需在函数声明后上“=delete;”,就可将该函数禁用。
// 定义一个单例类
class Singleton
{
public:
// 获取单例实例的静态方法
static Singleton* getInstance()
{
// 如果实例不存在,则创建一个新的实例
if(_ins == nullptr)
_ins = new Singleton;
// 返回单例实例
return _ins;
}
// 禁用拷贝构造函数
Singleton(Singleton &) = delete;
// 禁用赋值操作符
Singleton& operator=(Singleton &) = delete;
private:
// 私有构造函数,防止外部实例化
Singleton(){}
// 静态成员变量,用于存储单例实例
static Singleton* _ins;
};
// 初始化静态成员变量
Singleton* Singleton::_ins = nullptr;
int main()
{
// 获取单例实例
Singleton *ps = Singleton::getInstance();
// 尝试拷贝构造,但由于拷贝构造函数已被删除,会导致编译错误
// Singleton ps(*ps);
// 尝试赋值操作,但由于赋值操作符已被删除,会导致编译错误
// *ps = Singleton::getInstance();
return 0;
}
原始字符串文本
C/C++中提供了字符串,字符串的转义序列,给输出带来了很多不变,如果需要
原生义的时候,需要反转义,比较麻烦。
C++提供了 R"()",原生字符串,即字符串中无转义,亦无需再反义。但是注意()中的)"会导至提前结束。
#include <iostream>
using namespace std;
string path = "C:\Program Files (x86)\alipay\aliedit\5.1.0.3754";
string path2= "C:\\Program Files (x86)\\alipay\\aliedit\\5.1.0.3754";
string path3= R"(C:\Program Files (x86)\alipay\aliedit\5.1.0.3754)";
string path4= R"(C:\Program "Files" (x86)\\alipay\aliedit\5.1.0.3754)";
int main(int argc, char *argv[])
{
cout<<path<<endl;
cout<<path2<<endl;
cout<<path3<<endl;
cout<<path4<<endl;
return 0;
}