C++ day1 C++11的新特性

4.20
一.智能指针
顾名思义,“智能”的指针,可以在适当的时候自动释放分配的内存。
C++98/03中有auto_ptr实现堆空间的自动回收
C++11废弃了auto_ptr的同时,增加了三种智能指针

智能指针都是以类模板的方式实现的,shared_ptr(其中 T 表示指针指向的具体数据类型)的定义位于头文件,并位于 std 命名空间中。
1.shared_ptr
不同之处
1)内存使用:shared_ptr 智能指针可以共同使用同一块堆内存
2)计数机制:该类型智能指针在实现上采用的是引用计数机制,即便有一个 shared_ptr 指针放弃了堆内存的“使用权”(引用计数减 1),也不会影响其他指向同一堆内存的shared_ptr指针(只有引用计数为 0 时,堆内存才会被自动释放)
3)最常使用的智能指针

shared_ptr智能指针的创建

点击查看代码
//shared_ptr<T> 类模板中,提供了多种实用的构造函数
shared_ptr<int> p1; //不传入任何实参
shared_ptr<int> p2(nullptr); //传入空指针 nullpt
shared_ptr<int> p(new int(5))//明确其指向
shared_ptr<int> p = make_shared<int>(5);//C++11 标准中还提供了 std::make_shared<T> 模板函数
shared_ptr<int> p3;//调用拷贝构造函数
shared_ptr<int> p4(p3);//或者 shared_ptr<int> p4 = p3;//调用移动构造函数
shared_ptr<int> p5(move(p4)); //或者shared_ptr<int> p5 = move(p4);`
**ps**:空的 shared_ptr 指针,其初始引用计数为 0,而不是 1

自定义的释放规则
在初始化 shared_ptr 智能指针时,还可以自定义所指堆内存的释放规则,
这样当堆内存的引用计数为 0 时,会优先调用自定义的释放规则。

比如对于申请的动态数组,释放规则可以使用 C++11 标准中提供的
default_delete 模板类,我们也可以自定义释放规则
例子:

点击查看代码
#include <iostream>
using namespace std;
//自定义释放规则
void deleteInt(int* p) {
delete[]p;
}
int main()
{
//指定 default_delete 作为释放规则
shared_ptr<int> p1(new int[3], default_delete<int[]>());
//初始化智能指针,并自定义释放规则
shared_ptr<int> p2(new int[3], deleteInt);
return 0;
}

2.unique_ptr
shared_ptr 指针最大不同之处在于,unique_ptr 指针指向的堆内存无法同其它 unique_ptr 共享
也就说,每个unique_ptr指针都独自拥有对其所指堆内存空间的所有权

3.weak_ptr
shared_ptr是采用引用计数的智能指针,多个shared_ptr实例可以指向同一个动态对象,并维护了一个共享的引用计数器。
对于引用计数法实现的计数,总是避免不了循环引用的问题,weak_ptr可以有效解决这个问题

点击查看代码
#include <iostream>
using namespace std;
class CB;
class CA
{
public:
CA() { cout << "CA() called! " << endl; } ~CA() { cout << "~CA() called! " << endl; }
void set_ptr(shared_ptr<CB>& ptr) { m_ptr_b = ptr; }
void b_use_count() { cout << "b use count : " << m_ptr_b.use_count() << endl; }
void show() { cout << "this is class CA!" << endl; }
private:
shared_ptr<CB> m_ptr_b;
};
class CB
{
public:
CB() { cout << "CB() called! " << endl; } ~CB() { cout << "~CB() called! " << endl; }
void set_ptr(shared_ptr<CA>& ptr) { m_ptr_a = ptr; }
void a_use_count() { cout << "a use count : " << m_ptr_a.use_count() << endl; }
void show() { cout << "this is class CB!" << endl; }
private:
shared_ptr<CA> m_ptr_a;
};
int main(){
shared_ptr<CA> ptr_a(new CA());
shared_ptr<CB> ptr_b(new CB());
cout << "a use count : " << ptr_a.use_count() << endl;
cout << "b use count : " << ptr_b.use_count() << endl;
ptr_a->set_ptr(ptr_b);
ptr_b->set_ptr(ptr_a);
cout << "a use count : " << ptr_a.use_count() << endl;
cout << "b use count : " << ptr_b.use_count() << endl;
return 0; 
}

可以看到最后两个类都没有被析构。可以用weak_ptr来解决这个问题,可以把两个类中的一
个成员变量改为weak_ptr对象即可。weak_ptr不会增加应用计数,所以引用就构不成环

二.可变参数模板
C++11之前,类模版和函数模版中只能含固定数量的模版参数
C++11的新特性可变参数模板能够让您创建可以接受可变参数的函数模板和类模。
例子:

点击查看代码
`#include <iostream>
using namespace std;
//函数模板的参数个数为0到多个参数,每个参数的类型可以各不相同
template<class...T>
void funcName(T...args) {//args一包形参,T一包类型
cout << sizeof...(args) << endl;//sizeof...固定语法格式计算获取到模板参数的个数
cout << sizeof...(T) << endl;//注意sizeof...只能计算...的可变参
}
int main() {
funcName(100, 200, 300,400,600);
return 0;
}`

三.参数包展开
1.递归函数
2.使用if constexp
例子:

点击查看代码
#include <iostream>
using namespace std;
//if constexpr...()//constexpr代表的是常量的意思或者是编译时求值
//c++17中新增一个语句叫做编译期间if语句( constexpr if)
template<class T, class...U>
void funcName2(T frist, U...args) {
cout << "收到参数:" << frist << endl;
if constexpr (sizeof...(args) > 0) {//constexpr必须有否则无法编译成功,圆括号里面是常量表达式
funcName2(args...);
}
}
int main() {
funcName2(1,2, 3, 4, 5, 6);
return 0;
}

四.默认成员函数控制
在C++中对于空类编译器会生成一些默认的成员函数,比如:构造函数、拷贝构造函数、运算符重载、析构 函数&和const&的重载、移动构造、移动拷贝构造等函数。
C++11让程序员可以控制是否需要编译器生成
例子:

点击查看代码
#include <iostream>
using namespace std;
class ClassTest
{
public:
ClassTest(int num):n(num){}
ClassTest() = default; // 显式缺省构造函数 让编译器生成不带参数的默认构造函数,改成delete就不会生成了
ClassTest(const ClassTest&) = delete; // 禁止编译器生成默认的拷贝构造函数
ClassTest& operator=(const ClassTest& a); // 在类中声明,在类外定义时,让编译器生成默认赋值运算符重载
private:
int n;
};
ClassTest& ClassTest::operator=(const ClassTest& a) = default;//在类外让编译器默认生成
int main() {
ClassTest c1;
return 0;
}

五.新增容器
1.std::array
2.std::forward_list
3.unordered系列
博主之前用过了不多赘述,其实是想偷懒(bushi

posted @ 2025-04-21 00:03  北燃  阅读(50)  评论(0)    收藏  举报