文章目录
C++11
R “xxx(原始字符串)xxx”
- 原始字面量 R 可以直接表示字符串的实际含义,而不需要额外对字符串做转义或连接等操作
- 在R “xxx(raw string)xxx” 中,原始字符串必须用括号()括起来,括号的前后可以加其他字符串,所加的字符串会被忽略,并且加的字符串必须在括号两边同时出现
int main()
{
std::cout << "D:\hello\world\test.text" << std::endl;
std::cout << "D:\\hello\\world\\test.text" << std::endl;
std::cout << R"(D:\hello\world\test.text)" << std::endl;
string str1 = R"(D:\hello\world\test.text)";
cout << str1 << endl;
string str2 = R"luffy(D:\hello\world\test.text)luffy";
cout << str2 << endl;
#if 0
string str3 = R"luffy(D:\hello\world\test.text)robin"; // 语法错误,编译不通过
cout << str3 << endl;
return 0;
}
final
- final关键字用来限制某个类不能被继承或者某个虚函数不能被重写
- final修饰函数 只能修饰虚函数
- 要把final放在函数或者类的后面
override
- 确保在派生类之中声明的重写函数和基类的虚函数有相同的签名
- 明确表明会重写基类的虚函数
- 保证重写函数的正确性
- 要写到方法的后面
委托构造函数
说明
- 允许使用同一个类之中的构造函数调用其他的构造函数。从而简化相关变量的初始化
- 委托构造函数不能具有其他成员初始化表达式
class Test
{
public:
Test() {}
Test(int min):m_min(min),m_max(0){}
//cpp11之前
Test(int min,int max):m_min(min),m_max(max){}
//cpp11
//语法错误 委托构造函数不能具有其他成员初始化表达式
//Test(int min,int max):Test(min),m_max(max){}
Test(int min, int max) :Test(min)
{
m_max = min;
}
private:
int m_min;
int m_max;
};
注意
- 链式的调用构造函数最重要的一点是不能形成闭环(死循环),否则会在运行期报异常
- 如果要进行多层构造函数的链式调用,建议将构造函数的调用写在初始化列表而不是函数体的内部,否则编译器会提示形参的重复定义
继承构造函数
说明
- 继承构造函数可以让派生类直接使用基类的构造函数
- 如果在子类之中隐藏了父类之中的同名函数,也可以使用using的方式在子类之中使用父类的函数
class Base
{
public:
Base(int i) :m_i(i) {}
Base(int i, double j) :m_i(i), m_j(j) {}
Base(int i, double j, std::string k) :m_i(i), m_j(j), m_k(k) {}
void fun(int num){}
private:
int m_i;
double m_j;
std::string m_k;
};
class Child : public Base
{
public:
using Base::fun;//父类的函数被继承 相当于fun函数在同一个类之中的不同重载形式
using Base::Base;//继承构造函数
void fun(){}//隐藏了父类的同名函数
};
std::weak_ptr
- 弱引用的智能指针 不共享指针 不能操作资源 是用来监视std::shared_ptr
- 没有重载操作符*和->
- 构造和析构都不会引起引用计数的变换
- 作为一个旁观者监视std::shared_ptr之中是否存在资源
- use_count() 获得当前监视的对象的引用计数
- expired() 判断资源是否已经被释放
- reset() 清空资源 不监视任何资源
- lock() 获取管理所监测资源的shared_ptr对象
std::shared_ptr<int> sp1=std::make_shared<int>(520);
std::weak_ptr<int> wp=sp1;
std::shared_ptr<int> sp2=wp.lock();
cout<<wp.count()<<endl;//2
解决循环引用问题
智能指针的循环引用会造成内存泄露
NULL nullptr
- 如果源码是cpp 则NULL本质是0
- 如果源码时c则NULL本质是(void*)0
- cpp之中void* 类型无法隐士的转换为其他类型的指针,因此用0代替去解决空指针问题
- nullptr 专用于初始化空类型指针,不同类型的指针变量都可以使用 nullptr 来初始化
- nullptr 无法隐式转换为整形,但是可以隐式匹配指针类型。在 C++11 标准下,相比 NULL 和 0,使用 nullptr 初始化空指针可以令我们编写的程序更加健壮
constexpr链接
const什么时候是只读变量?什么时候是常量?
- 只有用字面量初始化的const常量才会进入符号表
- 使用其他变量初始化的const常量仍然是只读变量
- 被volatile修饰的const常量不会进入符号表
综上所述,在编译期间不能直接确定初始值的 const 标示符,都被作为只读变量处理。
当 const 修饰的变量是只读变量时,仅仅是说明不能通过这个只读变量修改内存的值,但是可以通过其他方法修改内存值。
const
- 从功能上来说这个关键字有双重语义:变量只读,修饰常量
- 变量只读并不等价于常量,二者是两个概念不能混为一谈
constexpr
- 常量表达式,指的就是由多个(≥1)常量(值不会改变)组成并且在编译过程中就得到计算结果的表达式。
- 在使用中建议将 const 和 constexpr 的功能区分开,即凡是表达“只读”语义的场景都使用 const,表达“常量”语义的场景都使用 constexpr
- 对于 C++ 内置类型的数据,可以直接用 constexpr 修饰,但如果是自定义的数据类型(用 struct 或者 class 实现),直接用 constexpr 修饰是不行的
- 常量表达式和非常量表达式的计算时机不同,非常量表达式只能在程序运行阶段计算出结果,但是常量表达式的计算往往发生在程序的编译阶段,这可以极大提高程序的执行效