首页 > 编程语言 >Qt/c++类型转换总结

Qt/c++类型转换总结

时间:2023-06-24 21:34:50浏览次数:48  
标签:类型转换 转换 Qt dynamic c++ cast 类型 指针

1、 static_castdynamic_cast、强制转换 (reinterpret_castconst_cast)、qobject_castqstatic_cast 以及 qdynamic_cast 的区别:

  1. static_cast
    • 用于执行静态类型转换,可以进行常见的类型转换,例如基本类型之间的转换、向上转型、向下转型(但没有运行时类型检查)等。
    • 在 C++ 中使用,适用于非多态类型和多态类型的转换(不执行动态类型检查)。
  2. dynamic_cast
    • 用于执行动态类型转换,在运行时检查类型的兼容性,确保安全的向下转型。
    • 用于多态类型的转换,需要基类中至少有一个虚函数。
    • 如果转换不安全,返回空指针(对于指针转换)或抛出 std::bad_cast 异常(对于引用转换)。
  3. 强制转换 (reinterpret_castconst_cast):
    • reinterpret_cast 用于执行低级别的类型转换,将一个指针或引用转换为不同类型的指针或引用,没有类型检查。
    • const_cast 用于去除 const 或 volatile 修饰符,允许对 const 或 volatile 对象进行非 const 或非 volatile 操作。
  4. qobject_cast
    • 是 Qt 框架提供的类型转换操作符,用于在 Qt 对象体系中进行类型转换。
    • 主要用于在 Qt 的对象之间进行安全的转换,例如在信号槽连接、查找子对象等场景。
    • 在运行时进行类型检查,如果转换失败,返回空指针或 null。
    • dynamic_cast 相似,但 qobject_cast 需要类继承自 QObject,且需要启用元对象系统 (MOC)。
  5. qstatic_castqdynamic_cast
    • qstatic_cast 是 Qt 框架提供的静态类型转换操作符,类似于 static_cast,用于常见的类型转换,如基本类型之间的转换、向上转型等。
    • qdynamic_cast 是 Qt 框架提供的动态类型转换操作符,类似于 dynamic_cast,用于多态类型的转换,进行向下转型,并在运行时检查类型的兼容性。
    • qstatic_castqdynamic_caststatic_castdynamic_cast 的差异主要是在 Qt 对象体系中的使用,允许与 Qt 特性(如信号槽系统)一起使用。

2、 细说static_castdynamic_cast

static_cast和dynamic_cast是C++中的两个类型转换操作符,它们在功能和使用上有一些重要的区别。

  1. static_cast:
    • static_cast是一种静态转换,用于在编译时期进行类型转换。
    • 它可以执行常见的类型转换,例如将指针或引用从一个类型转换为另一个类型,将算术类型转换为其他算术类型,以及在继承关系中进行向上转型。
    • 它不能执行动态类型转换,也就是说,它不能在运行时检查类型的兼容性。
    • static_cast没有运行时开销,因为类型检查是在编译时期进行的。
  2. dynamic_cast:
    • dynamic_cast是一种动态转换,用于在运行时期进行类型转换。
    • 它用于在继承关系中进行向下转型,即将基类指针或引用转换为派生类指针或引用。
    • 它进行类型检查,以确保转换是安全的。如果转换不安全,即目标类型不是源类型的派生类,dynamic_cast将返回空指针(对于指针转换)或抛出std::bad_cast异常(对于引用转换)。
    • dynamic_cast只能用于具有虚函数的类类型。它利用了运行时类型信息(RTTI)来进行类型检查。
    • dynamic_cast可能具有运行时开销,因为它需要在运行时进行类型检查。

总结: static_cast是一种在编译时期进行类型转换的静态转换操作符,适用于常见的类型转换,没有运行时开销。而dynamic_cast是一种在运行时期进行类型转换的动态转换操作符,适用于在继承关系中进行向下转型,具有类型检查的能力,但可能具有运行时开销。选择使用哪种转换操作符取决于具体的需求和转换的上下文。

3、 疑问: 那么是不是static_cast不可进行向下转型呢

实际上,static_cast 也可以用于向下转型。

向下转型是将指向基类对象的指针或引用转换为指向派生类对象的指针或引用。这种转换是不安全的,因为基类对象可能并不是派生类对象,所以需要进行类型检查来确保转换的安全性。在使用 static_cast 进行向下转型时,编译器不会进行类型检查,因此如果进行不安全的转换,可能会导致未定义行为。

然而,如果确保指向基类对象的指针或引用确实指向一个有效的派生类对象,那么使用 static_cast 进行向下转型是可以的。但是,这需要开发人员自己确保转换的安全性。

通常情况下,推荐使用 dynamic_cast 进行向下转型,因为它会在运行时进行类型检查,以确保转换的安全性。如果转换不安全,dynamic_cast 将返回空指针(对于指针转换)或抛出 std::bad_cast 异常(对于引用转换)。

因此,static_cast 可以用于向上转型和向下转型,但在向下转型时需要谨慎处理,确保转换的安全性。

4、reinterpret_cast详解

reinterpret_cast 是 C++ 中的一种强制类型转换操作符,它允许将一个指针或引用转换为不同类型的指针或引用,即使它们之间没有直接的关联。它是一种非常低级别的转换,没有类型检查,因此需要谨慎使用。

下面是一些 reinterpret_cast 的典型示例:

  1. 将指针转换为整数类型:
codeint* ptr = new int(10);
uintptr_t value = reinterpret_cast<uintptr_t>(ptr);

在这个示例中,ptr 是一个指向 int 的指针,通过 reinterpret_cast 将它转换为 uintptr_t 类型的整数。

  1. 将整数转换为指针类型:
codeuintptr_t value = 0x12345678;
int* ptr = reinterpret_cast<int*>(value);

这个示例将一个整数值 0x12345678 转换为 int* 类型的指针。

  1. 转换指针类型:
codestruct Base {
    virtual void foo() {}
};

struct Derived : Base {
    void bar() {}
};

Derived derivedObj;
Base* basePtr = &derivedObj;
Derived* derivedPtr = reinterpret_cast<Derived*>(basePtr);

在这个示例中,basePtr 是指向 Base 类对象的指针,通过 reinterpret_cast 将它转换为指向 Derived 类对象的指针。需要注意的是,这种转换不进行任何类型检查,因此需要确保转换的安全性。

  1. 类型转换与对象布局的转换:
codestruct A {
    int x;
    int y;
};

struct B {
    int z;
};

A a;
a.x = 1;
a.y = 2;
B* bPtr = reinterpret_cast<B*>(&a);

在这个示例中,a 是一个 A 类对象,通过 reinterpret_cast 将它的指针转换为指向 B 类对象的指针。这种转换可以用于在某些特定情况下对对象的布局进行转换,但需要非常小心,确保没有引发未定义行为。

需要注意的是,reinterpret_cast 的使用应该非常谨慎,因为它是一种非常底层的转换,很容易导致类型错误和未定义行为。除非对类型的布局和语义非常了解,并且确定转换的安全性,否则最好避免使用 reinterpret_cast。在大多数情况下,更好的选择是使用其他类型转换操作符,如 static_castdynamic_cast,它们提供了更严格的类型检查和更安全的转换。

标签:类型转换,转换,Qt,dynamic,c++,cast,类型,指针
From: https://www.cnblogs.com/linxmouse/p/17501711.html

相关文章

  • C/C++ 类型显式转换
    上一章,我提到了下面的代码#include<stdio.h>inta=(long)4;externchark=(int)'m';voidmain(void){printf("%s",a);printf("%f",k);}这里我需要纠正上一篇文章的错误,C语言不存在bool类型只要数字是大于0,那么相当于true否则就是false 其中,inta表示......
  • C++面试八股文:std::vector和std::list,如何选择?
    某日二师兄参加XXX科技公司的C++工程师开发岗位第24面:面试官:list用过吗?二师兄:嗯,用过。面试官:请讲一下list的实现原理。二师兄:std::list被称为双向链表,和C中手写双向链表本质上没有大的区别。list对象中有两个指针,一个指向上一个节点(node),一个指向下一个节点(node)。二师兄:与手写......
  • C++面试八股文:std::vector和std::list,如何选择?
    某日二师兄参加XXX科技公司的C++工程师开发岗位第24面:面试官:list用过吗?二师兄:嗯,用过。面试官:请讲一下list的实现原理。二师兄:std::list被称为双向链表,和C中手写双向链表本质上没有大的区别。list对象中有两个指针,一个指向上一个节点(node),一个指向下一个节点(node)。二师兄:与手......
  • [QML]从零开始QML开发(二)QML开发,浅谈控件、槽函数、锚等基本概念。QML和C++怎么交互?贯
    [QML]从零开始QML开发(二)QML开发,浅谈控件、槽函数、锚等基本概念。QML和C++怎么交互?贯彻落实MVC原则先看代码:importQtQuick2.12importQtQuick.Window2.12importQtQuick.Controls2.5Window{visible:truewidth:320height:480title:qsTr("HelloW......
  • C++ 核心指南之资源管理(上)
    C++核心指南(C++CoreGuidelines)是由BjarneStroustrup、HerbSutter等顶尖C++专家创建的一份C++指南、规则及最佳实践。旨在帮助大家正确、高效地使用“现代C++”。这份指南侧重于接口、资源管理、内存管理、并发等High-level主题。遵循这些规则可以最大程度地保证静......
  • Book-Effective C++ 改善程序与设计的55个具体做法
    Book-EffectiveC++改善程序与设计的55个具体做法让自己习惯C++AccustomingYourselftoC++条款01:视C++为一个语言联邦/ViewC++asafederationoflanguages.条款02:尽量以const,enum,inline替换#define/Preferconsts,enums,andinlinesto#defines.条款0......
  • [C/C++] Visual Stdio Code中多线程多源码文件编译、运行和调试
    搞了很久,记录一下:一.环境OS:Ubuntu20.04VSCode:1.77.0g++:g++(Ubuntu9.4.0-1ubuntu1~20.04.1)9.4.0二.配置文件下面两个文件先不要手动创建,下面第三章会讲到:task.json:编译程序的配置文件;launch.json:运行程序的配置文件.三.编译&运行1.打开main函数所在的cpp文......
  • qt---多语言支持
    qt---多语言支持keywords:翻译多语言可以翻译的有2种:界面上的,默认都是会翻译的,如果不想翻译,可以取消勾选相应的"可翻译的"代码中出现的文本,如果需要翻译,可以用tr包裹,如:tr("hello")准备好之后,工具->外部->Qt语言家->更新翻译,这样就可以在相应的ts文件中生成待翻译......
  • C++面试八股文:聊一聊指针?
    C++面试八股文:聊一聊指针?某日二师兄参加XXX科技公司的C++工程师开发岗位第17面:面试官:聊一聊指针?二师兄:好的。面试官:你觉得指针本质上是什么?二师兄:这要从内存地址开始说起了。如果有一块容量是1G的内存,假设它的地址是从0x00000000到0x3fffffff,每一个字节都对应一个地......
  • C++面试八股文:std::vector了解吗?
    某日二师兄参加XXX科技公司的C++工程师开发岗位第23面:面试官:vector了解吗?二师兄:嗯,用过。面试官:那你知道vector底层是如何实现的吗?二师兄:vector底层使用动态数组来存储元素对象,同时使用size和capacity记录当前元素的数量和当前动态数组的容量。如果持续的push_back(emplace_ba......