当前位置: 首页 > news >正文

C++纯虚函数

1、纯虚函数

纯虚函数是在基类中声明但没有具体实现的虚函数。它的作用是为派生类提供一个统一的接口规范,要求派生类必须实现该函数,否则派生类也会成为抽象类。

virtual 返回类型 函数名(参数表)=0;

“=0”表示不定义该虚函数的实现,没有函数体,只有函数声明;函数声明是为了在虚表中保留一个位置,将指向该虚函数体的指针定义为nullptr。

2、抽象类

含有纯虚函数的类是抽象类。抽象类是无法实例化对象的,因为纯虚函数没有实现部分,所以含有纯虚函数的类不能实例化对象。

抽象类使用规则:

(1)抽象类只能做其他类的基类,不能创建抽象类的对象

(2)抽象类不能用作参数类型、函数返回类型或显示类型转换。

(3)可以定义抽象类的指针的引用,此指针可以指向它的派生类的对象,从而实现运行时多态。

 3、四种类型转换

(1)static_cast 静态转换

static_cast <type_name> (表达式);

将表达式转换为 type_name 类型。

int a = 10;

char ch = 'x';

a = static_cast <int> (ch);

这里使用 static_cast<int>(ch) 把字符型变量 ch 转换为整型。在进行转换时,实际上是把字符 ch 对应的 ASCII 码值转换为整数。字符 'x' 的 ASCII 码值是 120,所以这个转换会把 ch 的 ASCII 码值 120 赋给整型变量 a。经过这行代码的执行,变量 a 的值就从原来的 10 变成了 120

1、基本数据类型转换:char short int long long long float double bool等;

2、指针转换:不能将常性指针给普通指针,

3、将void* 转换为其他类型

4、弃值表达:

5、左值转为右值 (无法将常性左值转换为右值)

6、用于类层次结构中基类和派生类之间指针或引用的转换。

上行转换:把派生类的指针或引用转换成基类表示是安全的。objx = static_cast<Object>(base);

下行转换:把基类指针或引用转换成派生类时,没有动态检查,是不安全的。

class Object
{
private:int value;
public:Object(int x= 0):value(x){}void func(){}
};
class Base :public Object {
private:int num;
public:Base(int x =0):Object(x+10),num(x){}void show()const{}
};class Test :public Object
{
private:int count;
public:Test(int x =0):Object(x), count(x + 10) {}void print()const{}
};
int main()
{Object objx;Test test;Base base;Object* op = &objx;Base* bp = static_cast<Base*>(op); //error //objx = static_cast<Object>(base);return 0;
}

不能把 基类指针或引用转换成派生类。bp指向objx时,bp要识别到Base类的num,而objx没有num。

(2)const_cast 去常性转换符

用来修改类型的const、volatile 属性。

内置类型:替换。

(3)reinterpret_cast  重新解释

reinterpret_cast <type_name> (expression);

type_name 必须是一个指针、引用、算数类型、函数指针或者成员指针。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针。 不产生亡值。

(4)dynamic_cast  动态转换

dynamic_cast <type_name> (expression);

允许在运行时刻进行类型转换,(目的:去查虚表中的RTTI信息,动态转换其实就是去识别RTTI)从而使程序能够在一个类层次结构中安全的转换类型。

可以把基类指针转换成派生类指针,或把指向基类的左值转换成派生类的引用。向上转换。

必须是public继承,基类要有虚函数。

如果是针对指针类型,失败结果是nullptr;

如果是针对引用类型,失败结果会抛出一个异常;(没有空引用)

在类层次进行上行转换时,dynamic_cast  和 static_cast的效果一样。

进行下行转换时,dynamic_cast 具有类型检查功能,比static_cast更安全。

示例,加以理解!!! 

typeid 运算符的工作原理
  • typeid(op):当对指针 op 使用 typeid 运算符时,typeid 会根据指针的静态类型来确定其类型信息。在这个例子中,op 的静态类型是 Object*,所以 typeid(op).name() 输出 Object*
  • typeid(*op):当对指针解引用后使用 typeid 运算符时,typeid 会在运行时根据对象的实际类型来确定其类型信息。具体步骤如下:
    • 获取虚函数表指针:通过 op 指针找到对象的内存地址,进而获取对象的虚函数表指针(vptr)。
    • 查找 type_info 指针:从虚函数表中获取指向 type_info 对象的指针。
    • 获取类型信息:通过 type_info 指针访问 type_info 对象,从中获取对象的实际类型信息。
  • dynamic_cast 的工作机制

    dynamic_cast 是 C++ 中用于在继承体系里进行类型转换的运算符,它会在运行时检查类型转换是否合法。

  • 当使用 dynamic_cast 进行指针类型转换时,若转换不合法会返回 nullptr

  • 当进行引用类型转换时,若转换不合法会抛出 std::bad_cast 异常。

例.1: 

 

1. Base* pb = dynamic_cast<Base*>(op); 非法的原因

op 是 Object 类型的指针,它实际指向的是 Test 类的对象 testBase 类和 Test 类虽然都继承自 Object 类,但它们是平行的派生类,彼此之间没有直接的继承关系。将指向 Test 对象的指针转换为 Base 类型的指针是不安全的,因为 Test 对象的内存布局和 Base 对象不同,强制转换会导致未定义行为。所以 dynamic_cast 在运行时检查到这种不合法的转换,会返回 nullptr

2. Test* tp = dynamic_cast<Test*>(op); 合法的原因

op 实际指向的就是 Test 类的对象 test。将指向 Test 对象的指针转换为 Test 类型的指针是合法的,因为指针所指向的对象类型和要转换的目标类型是一致的。dynamic_cast 在运行时检查发现 op 实际指向的就是 Test 类型的对象,所以可以安全地进行转换,返回一个有效的 Test 类型指针。

 例.2:

1. Base& rb = dynamic_cast<Base&>(robj); 不合法的原因

robj 实际引用的是 Test 类的对象 testBase 类和 Test 类是平行的派生类,它们之间没有直接的继承关系,且各自的内存布局和成员函数等实现可能不同。将 Test 对象的引用转换为 Base 对象的引用是不安全的,因为 Test 对象不具备 Base 对象特有的成员布局和语义。dynamic_cast 在运行时检查到这种不合法的转换后,会抛出 std::bad_cast 异常。

2. Test& rp = dynamic_cast<Test&>(robj); 合法的原因

robj 本身引用的就是 Test 类的对象 test。将 robj 转换为 Test 类型的引用,是将一个对象的引用转换为该对象所属类的引用,这是完全合法且安全的操作。dynamic_cast 在运行时检查到 robj 实际引用的就是 Test 对象,所以可以顺利完成转换,不会抛出异常。

 

相关文章:

  • 05-libVLC的视频播放器:设置倍速播放
  • C# 数据类型||C# 类型转换
  • 【Rust基础】使用Rocket构建基于SSE的流式回复
  • 借源网荷储之力,开启低碳园区 “绿色蝶变”
  • 优选算法系列(7.BFS 解决最短路问题)
  • RMSIN论文阅读
  • 日本留学常用的学习软件:开启你的国际化学术之旅
  • 判断一个整数是否为素数
  • 如何深入理解引用监视器,安全标识以及访问控制模型与资产安全之间的关系
  • 安全可靠+操作简捷——安科瑞预付费电表的用户体验升级
  • 《前端性能优化秘籍:打造极致用户体验》
  • Unity ShaderLab引用HLSL文件找不到其中函数
  • 国产三维CAD皇冠CAD(CrownCAD)在「电力电子制造业」建模教程:蘑菇台灯
  • c#清理释放内存
  • 【Unity】JSON数据的存取
  • hutool 工具类
  • 刷题 | 牛客 - js中等10题(更ing)1/54知识点解答
  • 【Python Cookbook】迭代器与生成器(一)
  • 【源码】30个Python小游戏
  • 总结【过往部分项目经历二(计算机图形学方向)】
  • 11家券商一季度净利翻番:9家利润超20亿,国泰海通居首
  • 赵乐际主持十四届全国人大常委会第十五次会议闭幕会并作讲话
  • “铁血防守”制造8年最快丢球,恐惧中的阿森纳什么也做不了
  • 工业富联一季度净利增长25%,云计算业务营收增长超50%
  • 建行一季度净利833.51亿同比下降3.99%,营收降5.4%
  • 郭继孚被撤销全国政协委员资格,此前为北京交通发展研究院长