C++11智能指针,强制转换,绑定函数----C++基础(第五期)

本文详细介绍了C++11中的智能指针(unique_ptr,shared_ptr,weak_ptr)以及它们的特点,包括独占和共享所有权、自定义释放机制、C++强制转换(如const_cast,static_cast,dynamic_cast,reinterpret_cast),可变参数模板、bind函数和function的使用,以及匿名函数的用法。
摘要由CSDN通过智能技术生成

C++11 智能指针

智能指针实质

实质:一个模板类(在堆上),只有一个成员----即传送进来的原始指针。

头文件#include<memory>

独占智能指针

该指针所指向的地址只能由此指针去访问,不能指针值传递,也不能拷贝构造。

int *p=new int;
*p=2;
unique_ptr<int>h(p);   //独占智能指针h,  原始指针p
//*h与*p所指地址一致。

unique_ptr<int>k(new int);

*h.get();   //获得原始指针,暂时获得,原智能指针不变
*h.release();    //获得原始指针,并将原来的智能指针置空

unique_ptr<int>h1; ~~h1=h;~~   
//这是错误的,独占智能指针不能值传递
h.reset();  //释放掉指针所占资源
h.reset(new int(3));  //释放掉指针所占资源,
                      //并重新申请资源,并赋值为3
h=nullptr;     //h置空,自动释放掉之前new的空间

int *p= new int[2];   //普通的指针数组
unique_ptr<int[]>p2(new int[2]); //独占智能指针数组
共享智能指针

多个指针可以指向同一个地址,其内部有计数(k2.use_count();)-----表示当前资源被多少指针引用,当计数为0时;自动释放此资源。

shared_ptr<int>K2(new int(20));

make_shared<指针类型>指针变量名(所指地址中存放的内容)
<----->shared_ptr<类型>指针变量名(new 类型(内容))

//指向一个值为10个9的string类型的shared_ptr 
shared_ptr<string> p1 = make_shared<string>(10, '9');
//指向一个值为42的int类型的shared_ptr 
shared_ptr<int> p2 = std::make_shared<int>(42);
弱智能指针

可以将共享指针或弱指针赋值给它,同时共享指针计数不会加一(解耦),弱指针与原来给它赋值的指针无联系。
weak_ptr<int>k1 = k3; //k3为一个shared_ptr智能指针,且此时k3计数并未加一

//使用弱智能指针前要判断该弱智能指针所指的资源是否过期
//(过期返回true)
    if(k1.expired()==true)
    {
       cout<<"k3已过期"<<endl;
    }
    k0.lock();//返回共享指针,若共享指针已过期;
             //则返回空的共享指针
智能指针删除器

自定义智能指针的释放

shared_ptr<int>k3(new int(15),delet);  
    //自定义的void delet()函数来删除智能指针
shared_ptr<int,void(*)(int *)>k4(new int(100),delet);
    //自定义的void delet(int *)函数来删除智能指针
    
   //以上对unique_ptr同样适用

C++11强制转换

const_cast(去常量化)

const_cast用于强制去掉不能被修改的常数特性,其去除常量性的对象一般为指针或引用。

const_cast<强制转换的目标类型>(变量名)

该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外, 强制转换的目标类型变量的类型必须要一样。

static_cast(静态转换)

static_cast<强制转换的目标类型>(变量名)

该运算符用于数据丢失转换(高字节类型向低字节类型转换),基本数据类型之间的转换,不能对常量,指针进行强制转换,空指针(void*)除外。

dynamic_cast (动态转换)

dynamic_cast<强制转换的目标类型>(变量名)

该运算符只能用于类间转换,支持类间交叉转换,不能操作普通数据。

该运算符可以用来:

  • 将派生类的指针或引用转换成基类的指针或引用。
  • 在基类存在虚函数的前提下(即父类子类间存在多态),将基类的指针或引用转换成派生类的指针或引用
reinterpret_cast

reinterpret_cast<强制转换的目标类型>(变量名)

该运算符主要有几种强制转换用途:将指针或引用转换为一个足够长度的整型、将整型转换为指针或引用类型。

C++11可变参数模板

template<class……A>   //……A是一个模板参数包
                    //(包含0---n个不同类型的参数)
  void function(A……arg)  //arg是一个函数参数包
  {
    cout<<sizeof……(arg)<<endl;    //打印出参数包中参数的个数
  }
  
 //……在参数左侧,代表一个可变参数,
 //……在一个参数右侧代表一个函数包的展开
 //(即一组可能相同,也可能不同的实参)
 
 //非递归方式取出所有参数
 template<typename... Args> 
 void print(const Args&... args) 
 {
   int dummy[] = {(std::cout << args << std::endl, 0)...}; 
   //匿名函数与变长数组
   }
 
 //以递归方式取出所有参数
 void print(){}
 template<typename T, typename ……T1>
    void print(T& a, T1& ……b)
    {
      cout<<a<<endl;
      print(b……);    //参数包展开
    }

省略符形参

省略符形参只能写在形参列表的最后一个位置。

void fun(……);
void fun(int i,……);
//当判断参数中第一个参数是整数,就会执行fun(int i,……);
//否则无论有好多参数,无论什么类型,只有不满足条件,都会执行fun(……);

bind绑定函数

头文件#include<functional>

例子:

#include<iostream>
#include<functional>

using namespace std;

void fun1(int a, int b)
{
   cout<<a<<b<<endl;
}
auto f1=std::bind(fun1,10,20);  //绑定函数
auto f2=std::bind(fun1,_1,_2);
//_1,_2  ……是占位符,表示该位置参数未被绑定,
//_1代表该位置参数由传入的第一个参数决定

int main()
{
 f1();   //等同于fun1(10,20);
 f2(40,50);  //等同于fun1(40,50);
 
 //f2的类型为std::function<void(int,int)>
 
 return 0;
}

bind 绑定类成员函数:

std::bind(&类名::函数名,&对象名,参数1,参数2……);

  1. 第一个参数是类成员函数地址
  2. 第二个参数是对象地址
  3. 该成员函数的参数……

C++11 function(函数指针的衍生物)

针对不同的可调用类型进行单独声明,则函数参数只能接收某种具体类型,这非常的不灵活,所以需要使用一种统一的方式保存可调用对象或者传递可调用对象(即函数),于是就有了std::function。

简单来说,bind可以将函数变成一个"变量",function可以将这个"变量"存起来。

std::function<函数返回值类型(函数参数各个类型)> 变量名;

上面bind的绑定函数后的变量类型就是function

例子:

void fun1(int a, int b)
{
   cout<<a<<b<<endl;
}
std::function<void(int, int)> fn = fun1;

int main()
{
  fn(20,30);   
  return 0;
}

//通常与bind绑定一起使用
std::function<void(int, int)> fn = std::bind(fun1,10,20);
// 这样 想要调用fun1(10,20);就可以直接调用fn();

//以上还有一种更通用的写法:
std::function<decltype(fun1(10,20))()> fn 
= std::bind(fun1,10,20);
//被bind绑定后,可以近似的将新的函数-----即fn()看作无参函数

C++11 匿名函数

[](参数1,参数2,……){} //匿名函数形式

[] 未定义变量,即在这个函数内使用任何外部变量都是错误的

[x,&y] 外部变量x,按值传递进入此函数,y按引用进入此函数(可以使用这两个外部函数)

[&] 可以使用外部变量,且所有外部变量都是按照引用进入此函数

[=] 可以使用外部变量,且所有外部变量都是按照值传递进入此函数

[&,x] x按照值传递进入此函数,其余外部变量按引用进入此函数

例子:

auto fun=[](int a){cout<<a<<endl;}
fun(3);   此时fun相当于函数指针
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

freejackman

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值