C/C++ static_cast、dynamic_cast、const_cast、reinterpret_cast 笔记整理

1、上行转换和下行转换的区别

1.1 上行转换

上行转换,就是取一个子类的对象的地址,并且按照其父类进行处理。因为子类是继承基类的,所以这种转换是不需要显式类型的转换的。而C++的多态就是按照这一特性实现的呢。上行转换(派生类的指针或者引用转换成基类)是安全的。
C/C++ static_cast、dynamic_cast、const_cast、reinterpret_cast 笔记整理_第1张图片
上行转换示例:

  //上行转换
  std::cout << "************上行转换************" << std::endl;
  class Driver driver1;
  class Base *base1 = &driver1;
  
  base1->display();
  std::cout << "mBase Data = " << base1->mBaseData << std::endl;
  std::cout << "********************************" << std::endl;
  std::cout << std::endl;

1.2下行转换

所谓下行转换是把基类的指针或引用转换为派生类表示,按照类的继承树来看,这种转换是有多种的,不知道转换成哪个子类,所以需要显式转换dynamic_cast (下文详细说明)。
下行转换示例:

  //下行转换
  class Base base2;
  class Driver *driver2;
  driver2 = (Driver *)&base2;
  std::cout << "************下行转换************" << std::endl;
  driver2->display();
  std::cout << "Base data = " << driver2->mBaseData << " Driver data = " << driver2->mDriverData << std::endl;
  std::cout << "********************************" << std::endl;

下面是上行转换和下行转换的对比:

/*************************************************************************
      > File Name: test.cpp
      > Author: 小和尚念经敲木鱼
      > Mail:  
      > Created Time: Fri 22 Apr 2022 11:27:07 PM CST
 ***********************************************************************/
#include 
#include 
using namespace std;
/************************************************************************
  * 文件说明
  * static_pointer_cast、dynamic_pointer_cast、
  * const_pointer_cast、reinterpret_pointer_cast
  * 学习笔记
************************************************************************/
class Base {
public:
  
  Base() {
    printf("%s @%d\n", __func__, __LINE__);
  }
  ~Base() {
    printf("%s @%d\n", __func__, __LINE__);
  }

  void display() {
    printf("%s @%d this is a base print display\n" , __func__, __LINE__);
  }
public:
  int mBaseData = 1;
};

class Driver : public Base {
public:
  Driver() {
    printf("%s @%d\n", __func__, __LINE__);
  }
  ~Driver() {
    printf("%s @%d\n", __func__, __LINE__);
  }

public:
  int mDriverData = 10;
};

int main(int agc,char * agv[])
{
  ///
  //上行转换
  std::cout << "************上行转换************" << std::endl;
  class Driver driver1;
  class Base *base1 = &driver1;

  base1->display();
  std::cout << "mBase Data = " << base1->mBaseData << std::endl;
  std::cout << "********************************" << std::endl;
  std::cout << std::endl;
  std::cout << std::endl;

  /
  //下行转换
  class Base base2;
  class Driver *driver2;
  driver2 = (Driver *)&base2;
  std::cout << "************下行转换************" << std::endl;
  driver2->display();
  std::cout << "Base data = " << driver2->mBaseData << " Driver data = " << driver2->mDriverData << std::endl;
  std::cout << "********************************" << std::endl;
  return 0;
}
//************上行转换************
//Base @22
//Driver @39
//display @29 this is a base print display
//mBase Data = 1
//********************************
//
//
//Base @22
//************下行转换************
//display @29 this is a base print display
//Base data = 1 Driver data = 1067911696
//********************************
//~Base @25
//~Driver @42
//~Base @25
/******************************end of file******************************/

上面简单的介绍上下行转换的基本概念,那如何区分上下行转换呢? 就是从 = 号从右往左看,如果右边是子类指针或者子类的引用,右边是父类的指针或者引用,按照继承树来看,则是上行转换。如果右边是父类的引用或者指针,左边是子类的指针或者引用,则是下行转换。这里还有一个知识点,那就是切割。切割的定义是覆盖方法和子类数据丢失的现象生成切割(slice)。
下面是产生切割的示例:

/*************************************************************************
      > File Name: shared_pointer_cast.cpp
      > Author: 小和尚念经敲木鱼
      > Mail:  
      > Created Time: Fri 22 Apr 2022 11:27:07 PM CST
 ***********************************************************************/
#include 
#include 
using namespace std;
/************************************************************************
  * 文件说明
  * static_pointer_cast、dynamic_pointer_cast、
  * const_pointer_cast、reinterpret_pointer_cast
  *
************************************************************************/
class Base
{
public:
 int mBaseData = 10;
 virtual void Test()
 {
  cout << "Base" <<endl;
 }
};
class Driver : public Base
{
public:
 int mDriverData = 100;
 virtual void Test()
 {
  cout << "Driver" <<endl;
 }
};
int main()
{
  Driver d;
  Base b = d;//直接赋值(产生切割)
  b.Test();

  Base& b2 = d;//使用引用赋值(不产生切割)
  b2.Test();

  Base* b3 = &d;//使用指针赋值(不产生切割)
  b3->Test();

  return 1;
}
//Out
//Base
//Driver
//Driver
/******************************end of file******************************/

2、static_cast、dynamic_cast、const_cast、reinterpret_cast区别

static_cast、dynamic_cast、const_cast、reinterpret_cast都是c/c++里面的转换方式,下面就针对这四种转换方式分别做解析。

2.1 static_cast 关键字

static_cast 是"静态转换",其是在编译期间进行转换的,如果转化失败则编译异常。该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。所以其只能用于良性转换,转换风险较低。
用法需要注意点如下:
(1)在用于类层次结构中基类(父类)和 派生类 (子类)之间指针或引用的转换。
进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;
进行下行转换(把基类指针或引用转换成派生类表示时,由于 没有动态类型检查,所以是不安全的
(2)用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
(3)把空指针转换成目标类型的空指针。
(4)把任何类型的表达式转换成void类型。
注意:static_cast不能转换掉expression的const、volatile、或者__unaligned属性。
使用示例
基本数据类型的转换:

/*******************************************************************************/
char a1 = 'a';
int b1 = static_cast<char>(a1);//正确,将char型数据转换成int型数据

double *a2 = new double;
void *b2 = static_cast<void*>(a2);//正确,将double指针转换成void指针

int a3 = 10;
const int b3 = static_cast<const int>(a3);//正确,将int型数据转换成const int型数据

const int a4 = 20;
int *b4 = static_cast<int*>(&a4);//编译错误,static_cast不能转换掉g的const属性
/*******************************************************************************/

类的static_cast转换:

/*************************************************************************
      > File Name: shared_pointer_cast.cpp
      > Author: 小和尚念经敲木鱼
      > Mail:  
      > Created Time: Fri 22 Apr 2022 11:27:07 PM CST
 ***********************************************************************/
#include 
#include 
#include 
using namespace std;

/************************************************************************
  * 文件说明
  * static_pointer_cast、dynamic_pointer_cast、
  * const_pointer_cast、reinterpret_pointer_cast
  *
************************************************************************/
class Base
{
public:
 int mBaseData = 10;
 virtual void Test() {
  cout << "Base" <<endl;
 }
};
class Driver : public Base
{
public:
 int mDriverData = 100;
 virtual void Test() {
  cout << "Driver" <<endl;
 }
};
int main()
{
  //类的下行转换,下行转换是不安全的
  Base *pBase = new Base();
  Driver *pDriver = static_cast<Driver *> (pBase); //下行转换是不安全的,所以下面打印是没有DriverData.
  std::cout << "Driver BaseData = " << pDriver->mBaseData << std::endl;
  std::cout << "Driver DriverData = " << pDriver->mDriverData << std::endl;
 
  //类的上行转换,上行转换是安全的
  std::cout << "--------------------------" << std::endl;
  Driver *pDriver2 = new Driver();
  Base *pBase2 = static_cast<Base*> (pDriver2); //上行转换是安全的
  std::cout << "Base BaseData = " << pBase2->mBaseData << std::endl;
}
//OUT
//Driver BaseData = 10
//Driver DriverData = 0
//--------------------------
//Base BaseData = 10
/*******************************************************************************/

2.2 dynamic_cast 关键字

dynamic_cast < type-id > (expression)
在上面类型中,Type-id可以是类的指针、类的引用或者void*。type-id 和 expression应该是一样的,如果type-id是指针(引用)的话,那么expression也应该是指针(引用)。

dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一模一样的。但是在进行下行转换时,dynamic_caststatic_cast更加智能些,其具有类型检查功能,比static_cast更加安全。而父类dynamic_cast到子类时,父类必须要有虚函数,否则编译器会报错,还可以用于类之间的交叉转换。

dynamic_cast将一个基类对象指针(或引用)cast到继承类指针,dynamic_cast会根据基类指针是否真正指向继承类指针来做相应处理, 即会作出一定的判断。

若对指针进行dynamic_cast,失败返回null,成功返回正常cast后的对象指针;
若对引用进行dynamic_cast,失败抛出一个异常,成功返回正常cast后的对象引用。
使用示例

/*************************************************************************
      > File Name: shared_pointer_cast.cpp
      > Author: 小和尚念经敲木鱼
      > Mail:  
      > Created Time: Fri 22 Apr 2022 11:27:07 PM CST
 ***********************************************************************/
#include 
#include 
#include 
using namespace std;
/************************************************************************
  * 文件说明
  * static_pointer_cast、dynamic_pointer_cast、
  * const_pointer_cast、reinterpret_pointer_cast
  *
************************************************************************/
class Base
{
public:
  Base() {
    cout << "Base" <<endl;
  }
public:
 int mBaseData = 10;
public:
 virtual void Test()
 {
  cout << "Base" <<endl;
 }
};

class Driver1 : public Base
{
public:
  Driver1() {
    cout << "Driver1" <<endl;
  }
public:
 int mDriver1Data = 100;
 virtual void Test()
 {
  cout << "Driver1" <<endl;
 }
};

class Driver2 : public Base
{
public:
  Driver2() {
    cout << "Driver2" <<endl;
  }
public:
 int mDriver2Data = 100;
public:
 virtual void Test()
 {
  cout << "Test" <<endl;
 }
};

class tDriver : public Driver1 , public Driver2 
{
public:
  tDriver() {
    cout << "tDriver" <<endl;
  }

  virtual void tDriverTest()
  {
    cout << "tDriver" <<endl;
  }

public:
  int mTDriverData = 100;
};

int main()
{
  class Driver1* driver1 = new Driver1();
  class Driver2* driver2 = new Driver2();

  class tDriver* tdriver1 = dynamic_cast<class tDriver*> (driver1);
  class tDriver* tdriver2 = dynamic_cast<class tDriver*> (driver2);

  // tDriver --> Base 转换的时候需要中间调整一下。
  class tDriver* tdriver3 = new tDriver();
  class Driver1* testDriver1 = dynamic_cast<Driver1*>(tdriver3);
  Base* base1 = dynamic_cast<Base*>(testDriver1);

  class tDriver* tdriver4 = new tDriver();
  class Driver2* testDriver2 = dynamic_cast<Driver2*>(tdriver4);
  Base* base2 = dynamic_cast<Base*>(testDriver2);

}
//OUT
//Base
//Driver1
//Base
//Driver2
//Base
//Driver1
//Base
//Driver2
//tDriver
//Base
//Driver1
//Base
//Driver2
//tDriver

2.3 const_cast 关键字

const_cast从字面来看是针对常量类型进行转换的,其可以修改类型的const和volatile属性。也是C++中唯一有此能力的类型转化符。
用法:
1.常量指针被转换成非常量指针,并且还是指向原来的对象。
2.常量引用转换成非常常量引用,并且还是依然指向原来的对象。
3.const_cast一般用来修改基本类型指针(char *、int * 、long *)等。
使用示例
对基本数据类型的使用:

 const int test_a = 10;
 int *test_a1 = const_cast<int*>(&test_a);//去掉const常量const属性
 std::cout<< "test_a1=" << *test_a1 << std::endl;

 const int test_b = 15;
 int &test_b1 = const_cast<int &>(test_b);//去掉const引用const属性
 std::cout << "test_b1=" << test_b1 << std::endl;

 const char *test_c = "hello";
 char *test_c1 = const_cast<char *>(test_c);//去掉const指针const属性
 std::cout << "test_c1=" << test_c1 << std::endl;

//OUT
//test_a1=10
//test_b1=15
//test_c1=hello

对类使用:

/*************************************************************************
      > File Name: shared_pointer_cast.cpp
      > Author: 小和尚念经敲木鱼
      > Mail:  
      > Created Time: Fri 22 Apr 2022 11:27:07 PM CST
 ***********************************************************************/

#include 
#include 
#include 
using namespace std;

/************************************************************************
  * 文件说明
  * static_pointer_cast、dynamic_pointer_cast、
  * const_pointer_cast、reinterpret_pointer_cast
  *
************************************************************************/
class Base
{
public:
  Base(int point,std::string data) :
    mBasePoint(point),
    mBaseData(data) {
    std::cout << "Base point:" << point << std::endl;
    std::cout << "Base Data:" << data << std::endl;
  }
public:
 int mBasePoint;
 std::string mBaseData;
public:
  void Base_Test() {
    std::cout << "Point:" << mBasePoint << "\t Data:" << mBaseData << std::endl;
  }
};

class Driver1 : public Base
{
public:
  Driver1(int point, std::string data) : Base(point, data) {
    mDriverPoint = point + 10;
    mDriverData = data;
    cout << "Driver1" <<endl;
  }
public:
  int mDriverPoint;
  std::string mDriverData;
public:
  void Display() {
    cout << "Driver1 DriverPoint:" << mDriverPoint << " Data:" << mDriverData <<endl;
  }
  void SetData(std::string data) {
    mDriverData = data;
  }
};

int main()
{
  const Base* base_test = new Base(10,"this is a test!");
  Base* base_test_1 = const_cast<Base*>(base_test);
  base_test_1->Base_Test();


  Driver1* driver1 = new Driver1(20, "this is a demo!");
  driver1->SetData("##############\n");
  //const_cast 把const修饰的类型转换为非const类型
  Driver1* driver2 = const_cast<Driver1*> (driver1);
  driver2->Display();

  return 0;
}

2.4 reinterpret_cast 关键字

reinterpret_cast
new_type必须是一个指针、引用、算术类型、函数指针或者成员指针。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,再把该整数转换成原类型的指针,还可以得到原先的指针值。但是reinterpret_cast意图执行低级转型,实际动作(及结果)可能取决于编辑器,这也就表示它不可移植。按照理解就是可以把一个整型转换为指针,也可以把一个指针转换为整型。

使用示例

int display(int data) {
  std::cout << __func__ <<"data:"  << data << std::endl;
  return 0;
}

typedef int (*test_func)(int);

int main(){
  int data = 10;
  test_func fun_1 = display;
  fun_1(data);

  //将函数display转换成一个值
  auto value = reinterpret_cast<test_func>(display);
  std::cout << "value:" << value << std::endl;

  //将函数value转换成一个函数
  test_func test_value = reinterpret_cast<test_func>(value);
  test_value(1000);

  //不能直接将数据转换成函数进行使用
  //test_func fun2 = reinterpret_cast(&data);
  //fun2(data);//...处有未经处理的异常: 0xC0000005: Access violation

  return 0;
}
//Out
//displaydata:10
//value:1
//displaydata:1000
//段错误 (核心已转储)

从上面中我们可以看出,不能直接将一个数据转换成函数进行使用。reinterpret_cast 在转化数据成函数时,数据本身应该是由函数转换得来的,不然会出问题。
类之间的使用

/*************************************************************************
      > File Name: shared_pointer_cast.cpp
      > Author: 小和尚念经敲木鱼
      > Mail:  
      > Created Time: Fri 22 Apr 2022 11:27:07 PM CST
 ***********************************************************************/

#include 
#include 
#include 
using namespace std;
/************************************************************************
  * 文件说明
  * static_pointer_cast、dynamic_pointer_cast、
  * const_pointer_cast、reinterpret_pointer_cast
  *
************************************************************************/
class TestA
{
public:
	int mA;
};
 
class TestB 
{
public:
  int mB;
};
 
class TestC : public TestA, public TestB {};

int main(){
  TestC test_c;
  printf("%p\n%p\n%p\n", &test_c, reinterpret_cast<TestB*>(&test_c), static_cast <TestB*>(&test_c));
  return 0;
}
//Out
//0x7ffdc350a320
//0x7ffdc350a320
//0x7ffdc350a324
/******************************end of file******************************/

前两个的输出值是相同的,而最后一个则会在原基础上偏移4个字节,这是因为static_cast计算了父子类指针转换的偏移量,并将之转换到正确的地址。test_c里面有mA和mB的成员变量,转换成TestB的指针时指到了mB的地方。reinterpret_cast没有进行这个操作。所以和前面一个一样。** reinterpret_cast慎用**

3、智能指针之间的转换

前面介绍了几种指针之间的转换方式,下面我们就来看一下智能指针的转换方式。

3.1 std::static_pointer_cast 关键字

std::static_pointer_cast 是static_cast针对智能指针的转换。其可以上行转换,也可以下行转换,但是下行转换的时候是不安全的,并且子类的指针是不能访问自己内部的成员函数和成员变量,只能访问父类的成员变量和成员函数。
使用示例

/*************************************************************************
      > File Name: shared_pointer_cast.cpp
      > Author: 小和尚念经敲木鱼
      > Mail:  
      > Created Time: Fri 22 Apr 2022 11:27:07 PM CST
 ***********************************************************************/

#include 
#include 
#include 
#include 
using namespace std;

class Base
{
public:
  Base() {
    std::cout << __func__ << std::endl;
  }
  virtual ~Base() {
    std::cout << __func__ << std::endl;
  }
  void BaseDisplay() {
    std::cout << "mBase data:" << mBaseData << std::endl;
  }
protected:
  int mBaseData = 10;
};
 
class Driver : public Base
{
public:
  Driver() {
    std::cout << __func__ << std::endl;
  }
  virtual ~Driver() {
    std::cout << __func__ << std::endl;
  }
  void DriverDisplay() {
    std::cout << "mDriver data:" << mDriverData << std::endl;
  }
private:
  int mDriverData = 100;
};
 
int main() {
  //上行转换 子类 ---> 父类
  std::cout << "-----------------上行转换-----------------------" <<std::endl;
  std::shared_ptr<Driver> pdriver1 = std::make_shared<Driver>();
  shared_ptr<Base> pbase1 = std::static_pointer_cast<Base>(pdriver1); 
  pbase1->BaseDisplay();
  //调用不了
  //pbase1->DriverDisplay();
  pdriver1.reset();
  std::cout << "----------------下行转换------------------------" <<std::endl;
  //下行转换 父类 ---> 子类
  std::shared_ptr<Base> pbase2 = std::make_shared<Base>();
  shared_ptr<Driver> pdriver2 = std::static_pointer_cast<Driver>(pbase2); 
  pdriver2->BaseDisplay();
  pdriver2->DriverDisplay();
  pdriver2.reset();
  return 0;
}
//OUT
//-----------------上行转换-----------------------
//Base
//Driver
//mBase data:10
//----------------下行转换------------------------
//Base
//mBase data:10
//mDriver data:0 打印为0 不安全
//~Base
//~Driver
//~Base
/******************************end of file******************************/

3.2 std::dynamic_pointer_cast 关键字

dynamic_pointer_cast使用方法和dynamic_cast类似.其在用于下行转换的时候具有类型的检测功能.
使用示例

/*************************************************************************
      > File Name: shared_pointer_cast.cpp
      > Author: 小和尚念经敲木鱼
      > Mail:  
      > Created Time: Fri 22 Apr 2022 11:27:07 PM CST
 ***********************************************************************/

#include 
#include 
#include 
#include 
using namespace std;

/************************************************************************
  * 文件说明
  * static_pointer_cast、dynamic_pointer_cast、
  * const_pointer_cast、reinterpret_pointer_cast
  *
************************************************************************/
class Base {
public:
  Base() {
    std::cout << __func__ << std::endl;
  }
  virtual ~Base() {
    std::cout << __func__ << std::endl;
  }
public:
  void BaseDisplay() {
    std::cout << "mBaseData:" << mBaseData << std::endl;
  }
protected:
  int mBaseData = 10;
};
class Driver : public Base {
public:
  Driver() {
    std::cout << __func__ << std::endl;
  }
  virtual ~Driver() {
    std::cout << __func__ << std::endl;
  }
  void setData(std::string& str) {
    mDriverData = str;
  }
  void DriverDisplay() {
    std::cout << __func__ << " DriverData:"  << mDriverData << std::endl;
  }
public:
  std::string mDriverData = "this is DriverData";
};

class DriverImpl : public Driver {
public:
  DriverImpl() {
    std::cout << __func__ << std::endl;
  }
  ~DriverImpl() {
    std::cout<< __func__ << std::endl;
  }
  void DriverImplDisplay() {
    std::cout <<"mDriverImplData:" << mDriverImplData << std::endl; 
  }
public:
  int mDriverImplData = 200;
};

int main (int argc,char *argv[])
{
  std::cout << "---------------上行转换----------------" << std::endl;
  //上行转换
  std::shared_ptr<Driver> impl1 = std::make_shared<Driver>();
  std::shared_ptr<Base> base1 = std::dynamic_pointer_cast<Base> (impl1);
  //访问不了子类的函数
  base1->BaseDisplay();
  base1.reset();
  impl1.reset();

  std::cout << "---------------下行转换----------------" << std::endl;
  //下行转换 自动检测类 安全
  std::shared_ptr<Base> base2 = std::make_shared<DriverImpl>();
  std::shared_ptr<Driver> driver2 = std::dynamic_pointer_cast<Driver> (base2);
  std::cout << std::endl;

  driver2->BaseDisplay();
  driver2->DriverDisplay();

  std::cout << std::endl;
  std::shared_ptr<DriverImpl> impl2 = std::dynamic_pointer_cast<DriverImpl> (base2);

  impl2->DriverImplDisplay();
  impl2->DriverDisplay();
  impl2->BaseDisplay();

  std::cout << std::endl;
  impl2.reset();
}

//OUT
//---------------上行转换----------------
//Base
//Driver
//mBaseData:10
//~Driver
//~Base
//---------------下行转换----------------
//Base
//Driver
//DriverImpl
//
//mBaseData:10
//DriverDisplay DriverData:this is DriverData
//
//mDriverImplData:200
//DriverDisplay DriverData:this is DriverData
//mBaseData:10
//
//~DriverImpl
//~Driver
//~Base
/******************************end of file******************************/

3.3 std::const_pointer_cast 关键字

std::dynamic_pointer_cast和dynamic_cast使用方法类似。
使用示例

/*************************************************************************
      > File Name: shared_pointer_cast.cpp
      > Author: 小和尚念经敲木鱼
      > Mail:  
      > Created Time: Fri 22 Apr 2022 11:27:07 PM CST
 ***********************************************************************/

#include 
#include 
#include 
#include 
using namespace std;

/************************************************************************
  * 文件说明
  * static_pointer_cast、dynamic_pointer_cast、
  * const_pointer_cast、reinterpret_pointer_cast
  *
************************************************************************/
class Base {
public:
  Base() {
    std::cout << __func__ << std::endl;
  }
  virtual ~Base() {
    std::cout << __func__ << std::endl;
  }
public:
  void BaseDisplay() {
    std::cout << "mBaseData:" << mBaseData << std::endl;
  }
protected:
  int mBaseData = 10;
};
class Driver : public Base {
public:
  Driver() {
    std::cout << __func__ << std::endl;
  }
  virtual ~Driver() {
    std::cout << __func__ << std::endl;
  }
  void setData(std::string& str) {
    mDriverData = str;
  }
  void DriverDisplay() {
    std::cout << __func__ << " DriverData:"  << mDriverData << std::endl;
  }
public:
  std::string mDriverData = "this is DriverData";
};

class DriverImpl : public Driver {
public:
  DriverImpl() {
    std::cout << __func__ << std::endl;
  }
  ~DriverImpl() {
    std::cout<< __func__ << std::endl;
  }
  void DriverImplDisplay() {
    std::cout <<"mDriverImplData:" << mDriverImplData << std::endl; 
  }
public:
  int mDriverImplData = 200;
};

int main (int argc,char *argv[])
{
  std::shared_ptr<int> data1 = std::make_shared<int>(100);
  std::shared_ptr<const int> data2 = std::const_pointer_cast<const int>(data1);
  std::cout << "data2 value: " << *data2 << std::endl;
  *data1 = 20;
  std::cout << "data2 value: " << *data2 << std::endl;
  //执向同一地址
  std::cout << "data1:"<< data1 << "\tdata2:" << data2 << std::endl;

  const std::shared_ptr<Base> base1 = std::make_shared<Base>();
  std::shared_ptr<Base> driver1 = std::const_pointer_cast<Base> (base1);
  std::cout << "base1:" << base1 << "\tdriver1:" << driver1 << std::endl;
  driver1->BaseDisplay();
}

//OUT
//data2 value: 100
//data2 value: 20
//data1:0x1cb0c38 data2:0x1cb0c38
//Base
//base1:0x1cb1078 driver1:0x1cb1078
//mBaseData:10
//~Base
/******************************end of file******************************/

3.4 std::reinterpret_pointer_cast 关键字

本地环境没有升级C++的库,所以reinterpret_pointer_cast

4、总结

std::static_cast、std::dynamic_cast、std::const_cast、std::reinterpret_cast是针对不同场景下的使用,优先使用std::dynamic_cast,其次才是使用std::static_cast,针对const类型的使用std::const_cast,如果前后可以确认的转换数据结构的可以使用std::reinterpret_cast。而std::static_pointer_cast、std::dynamic_pointer_cast、 std::const_pointer_cast、std::reinterpret_pointer_cast是针对智能指针使用转换类型的关键字,用法上面也进行了分析。最后,如有错误,望大佬斧正。

你可能感兴趣的:(C/C++,c++,c语言)