C++:类的转换(隐式转换、显式转换、static_cast、dynamic_cast、const_cast、reinterpret_cast等)

类的转换

类的转换包括:隐式转换和显式转换

(1)隐式转换

将一个类对象的类型转为另一种类类型。如果一个类定义了转换构造函数或者转换运算符,那么编译器可以自动执行隐式转换

class B
{
public:
	double dVal;

public:
	B(double dVal_) : dVal(dVal_) {}
	B(int iVal_) :dVal(iVal_) {}

};
class A
{
public:
	int iVal;

public:
	A() {};
	A(int iVal_) : iVal(iVal_) {}
	A(B bObj)
	{
		iVal = (int)bObj.dVal;
	}

};
void main()
{
	B bObj(3.14);
	A aObj=bObj; //隐式地调用A的转换构造函数,将B转换成A
	std::cout << aObj.iVal << std::endl; //打印:3
}

上述代码类A和类B都定义了转换构造函数,在实际使用的时候,可以自动进行隐式转换(类型转换)

(2)禁止隐式转换

explicit A(B bObj){...}

将A的转换构造函数使用关键字explicit进行修饰之后,A aObj = bObj;将会报错,这个时候必须使用显式类型转换,实现类B对象向类A对象的转换

(3)显式转换

使用显式转换操作符 static_cast、dynamic_cast、reinterpret_cast 和 const_cast 来实现不 同类型之间的转换

A.static_cast

  • 用于基本的类型转换、类层次结构间的上行转换(派生类指针向基类指针的转换)
    和下行转换(基类指针向派生类指针的转换)
  • 在编译时进行类型检查,不提供运行时类型检查:
  • 编译时类型检查:编译时编译器会检查代码中的类型错误和不一致之处,并给出 相应警告或提示。这种类型检查主要发生在编译阶段,在生成可执行文件之前
  • 运行时类型检查:程序运行时根据对象的实际类型检查和处理类型相关的问题
  • 在执行向上转型和向下转型时不提供动态检查,因此不安全
// static_cast 向下转换 01:指向派生类对象
Base *base_ptr = new Drived(0, 01);
base_ptr->showInfo(); // (静态绑定)打印:BaseClass! 0 
base_ptr->virtual_showInfo(); // (动态绑定)打印:virtual method in DrivedClass! 1 
Drived *drived_ptr = static_cast<Drived *>(base_ptr);
drived_ptr->showInfo(); // 打印:DrivedClass! 1 
drived_ptr->virtual_showInfo(); // 打印:virtual method in DrivedClass! 1 
cout << "*****************************" << endl;

// static_cast 向下转换 02:不指向派生类对象,这样转没有意义,属于非法转换 
Base *base_ptr01 = new Base(1);
Drived *drive_ptr01 = static_cast<Drived *>(base_ptr01); 
drive_ptr01->showInfo(); // 打印:DrivedClass! -1163005939 
drive_ptr01->virtual_showInfo(); // 打印:virsual method in BaseClass! 1 
cout << "*****************************" << endl;

// static_cast 向上转换 
Drived *drive_ptr02 = new Drived(2, 22); 
drive_ptr02->showInfo(); // 打印:DrivedClass! 22 
drive_ptr02->virtual_showInfo(); // 打印:virtual method in DrivedClass! 22 
Base *base_ptr02 = static_cast<Base *>(drive_ptr02);
base_ptr02->showInfo(); // 打印:BaseClass! 2 
base_ptr02->virtual_showInfo(); // (动态绑定)打印:virtual method in DrivedClass! 22 
cout << "*****************************" << endl;

B.dynamic_cast

  • 用于类层次结构间的安全向下转换:基类强转为派生类(父类强转为子类)
  • 运行时类型检查,可以检查是否进行有效的类型转换
  • 要确保基类指针或引用实际上指向派生类对象,如果转换不可行,则返回空指针(对指针进行转换)或抛出 std::bad_cast 异常(对引用进行转换)
  • 只能用于含有虚函数的类
// dynami_cast 向下转换 01:不指向派生类 
Base *base_ptr03 = new Base(3);
// 要求基类指针指向的实际对象是派生类的对象。否则,转换将失败并返回空指针 
Drived *drive_ptr03 = dynamic_cast<Drived *>(base_ptr03);
if (drive_ptr03){
	drive_ptr03->showInfo(); 
	drive_ptr03->virtual_showInfo(); 
}
else 
	cout << "转换失败!" << endl; // 打印:转换失败! 
cout << "*****************************" << endl; 
// dynami_cast 向下转换 02:指向派生类
Base *base_ptr04 = new Drived(4, 44);
Drived *drive_ptr04 = dynamic_cast<Drived *>(base_ptr04); 
drive_ptr04->showInfo(); // 打印:DrivedClass! 44
drive_ptr04->virtual_showInfo(); // 打印:virtual method in DrivedClass! 44

C.reinterpret_cast

  • 不进行类型检查或安全性检查,完全依赖于程序员自己来确保类型转换的正确性
  • 用于指针或引用之间的类型转换,也可用于不同类型之间的转换,如将整型转换为指针类型。
  • 执行非常低级的转换,可能会导致未定义行为。

D.const_cast

  • 添加 const 属性:给常规变量、指针或引用添加 const 属性
  • 删除 const 属性:去除常规常量、顶层指针和引用的 const 属性
  • 不要修改去除了 const 的 nonConstValue 变量,因为其行为是未定义的
  • const_cast 去除 const 属性主要作用是赋值和用作函数参数传递,避免重载带有 const参数的函数

相关推荐

  1. C#中类型转换类型转换

    2024-07-20 11:34:10       33 阅读
  2. mysql转换规则

    2024-07-20 11:34:10       55 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-20 11:34:10       57 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-20 11:34:10       60 阅读
  3. 在Django里面运行非项目文件

    2024-07-20 11:34:10       48 阅读
  4. Python语言-面向对象

    2024-07-20 11:34:10       60 阅读

热门阅读

  1. abc362(abcde)

    2024-07-20 11:34:10       16 阅读
  2. [jieba_fast][python]jieba_fast所有whl文件下载地址汇总

    2024-07-20 11:34:10       19 阅读
  3. 【Android】本地化的实现

    2024-07-20 11:34:10       17 阅读
  4. 刷题Day57|107. 寻找存在的路径

    2024-07-20 11:34:10       17 阅读
  5. PEFT的几种方式

    2024-07-20 11:34:10       15 阅读
  6. springSecurity学习之springSecurity过滤web请求

    2024-07-20 11:34:10       21 阅读
  7. GEE错误:Error: Encoded object too large. (Error code: 3)

    2024-07-20 11:34:10       16 阅读
  8. Spring 定时任务Scheduler监控异常和超时取消

    2024-07-20 11:34:10       16 阅读