CPP11新特性
CPP11新特性

基础,基本上都是c++03
其他部分特性,根据需要选择。
explicit 关键字

测试代码
#include <iostream>
#include <string>
using namespace std;
class student {
public:
student(int age) {
this->age = age;
cout << "age 参构造器" << endl;
}
student(int age, string name) {
this->age = age;
this->name = name;
cout << "有参构造器" <<"name="<<name <<",age="<<age << endl;
}
void desc() {
cout << "age=" << age << ",name=" << name << endl;
}
~student() {
}
private:
int age;
string name;
};
int main() {
student s1(13); // 显示构造
student s3 = 165; // 隐私构造
student s2(19, "校花"); // 显示构造
student s4 = { 20, "janny" }; // 隐私构造 c++11 之前编译无法通过,新特性
return 0;
}
打印结果
age 参构造器
age 参构造器
有参构造器name=校花,age=19
有参构造器name=janny,age=20
D:\code\cpp\ConsoleApplication1\Release\虚函数表项目.exe (进程 23668)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
可以看到,后面两个构造器,隐式的调用了构造器,虽然并没有声明这种构造方式。
构造器默认是隐式的。
将构造器在改成显式的。
explicit student(int age) {
this->age = age;
cout << "age 参构造器" << endl;
}
explicit student(int age, string name) {
this->age = age;
this->name = name;
cout << "有参构造器" <<"name="<<name <<",age="<<age << endl;
}
即在构造器前添加关键字:explicit
可以看到编译器报错了,后面两个隐式构造的函数,无法构造,没有合适的构造器。

作用
有些时候,student s3 = 165; // 隐私构造
这种写法有可能会造成歧义,避免出现这种构造方式。
左值和右值
左值必须可以为可以赋值的值,比如一个函数就不是可以赋值的值
主要是物理机器的规范,内存、寄存器之类
函数返回值当引用

都是骚操作啊,这么用真的好吗?
array

int main() {
// 存3个int
array<int, 3> arr;
return 1;
}
类型转换

float a = 1;
int b = (int)a;

如上图所示,总共是四种。
// 转换方式1
int i2 = static_cast<int>(a); // 强制类型转换
int* addr = (int*)0x8888; // 将整数转换成指针
// 转换方式2
int* addr2 = reinterpret_cast<int*>(0x888888);
一般情况下,不建议进行类型转换,除非你很清楚类型是什么。
智能指针
使用

原理
我就猜一下,这里还需要去验证。
智能指针首先是一个模板类,他其实就是一个包装器,自己持有了一个属性,只不过这个属性有些特殊,不是基础类型,而是指针类型。
因为c++的函数中,局部变量会在函数中断(异常)或者结束(return或者执行完成)之后释放局部变量,但是不会释放指针类型。
如代码:
void test() { int a = 1; // 普通变量 int* v = new int(33); // 创建了一个指针变量 } int main() { test(); // 在这里 test函数执行完成之后,test函数中定义的变量a就会被释放 // 而指针变量是不会释放的,并且创建指针也申请了内存,如果不释放,就会造成内存泄漏 return 1; }
所以,智能指针干了什么事情呢?
他把指针对象包装了一下,把自己伪装成了一个局部变量,如果函数中断或者结束后,销毁局部变量的时候,会调用他的析构函数,他在析构函数中释放了指针。
void test2() { // 这不就是一个普通局部变量的样子吗? auto_ptr<int> ip1(new int(222)); } int main() { test(); test2(); // 执行到这里,test2函数中声明的变量会都被释放 return 1; }
智能指针的源代码论证
_EXPORT_STD template <class _Ty> // 模板类 _Ty 泛型
class auto_ptr { // wrap an object pointer to ensure destruction
public:
// 构造函数 将传入的指针对象,赋值给Myptr
explicit auto_ptr(_Ty* _Ptr = nullptr) noexcept : _Myptr(_Ptr) {}
// .... 删除一大堆的运算符重载函数...
// 析构函数,删除指针
~auto_ptr() noexcept {
delete _Myptr;
}
// 私有属性 指针持有对象
private:
_Ty* _Myptr; // the wrapped object pointer
};
关于构造函数哪里:
explicit auto_ptr(_Ty* _Ptr = nullptr) noexcept : _Myptr(_Ptr) {}
explicit auto_ptr
: 这是类的构造函数定义,并且带有explicit
关键字。这意味着这个构造函数不能被隐式调用。(_Ty* _Ptr = nullptr)
: 这是构造函数的参数,接受一个指针_Ptr
,默认值是nullptr
。noexcept
: 这个关键字表示这个构造函数不会抛出异常。: _Myptr(_Ptr)
: 这部分是初始化列表。它的作用是直接初始化类的成员变量_Myptr
,将其设置为传入的参数_Ptr
。通过使用初始化列表,可以确保成员变量在构造函数体执行之前被正确初始化。
结论
就是,智能指针,在创建的时候,将指针对象赋值给自己内部的参数MyPtr
,在销毁的时候,会调用自己的析构函数将指针删除。
不过,这个东西在C++11之后,不推荐使用了~~
由于它有许多已知问题(如所有权转移等),在C++11之后被弃用,推荐使用其他智能指针如
shared_ptr
或unique_ptr
。

unique_ptr
针对智能指针的问题,不允许显式 右值赋值和构造操作。

左值复制构造也不允许
如何转移指针?

通过move,将先前的指针释放,转移到新的指针上。
本质上还是没有解决问题,只是不让这样操作了。

shared_ptr
介绍

问题
循环引用问题,计数器无法归零。类似于Java的循环引用问题,因此出现了弱引用。
weak_ptr
介绍
