首页 > 编程语言 >C++虚函数、static_cast、dynamic_cast

C++虚函数、static_cast、dynamic_cast

时间:2023-07-30 17:23:08浏览次数:42  
标签:函数 int dynamic C++ cast static 指针

       C++虚函数:当一个类中拥有至少一个虚函数,那么编译器就会构建出一个虚函数表来指示这些函数的地址,假如继承该类的子类定义并实现了一个同名并具有同样函数签名的方法重写了基类中的方法,那么虚函数表会将该函数指向新的地址。
       此时多态性就体现出来了:当我们将基类的指针或引用指向子类的对象的时候,调用方法时,就会顺着虚函数表找到对应子类的方法而非基类的方法。
       当然虚函数表的存在对于效率上会有一定的影响,首先构建虚函数表需要时间,根据虚函数表寻到到函数也需要时间。
       因为这个原因如果没有继承的需要,一般不必在类中定义虚函数。但是对于继承来说,虚函数就变得很重要了,这不仅仅是实现多态性的一个重要标志,同时也是dynamic_cast转换能够进行的前提条件。

 

static_cast< new_type >(expression)
dynamic_cast< new_type >(expression)

new_type:目标数据类型 expression:原始数据类型变量或者表达式

1、static_cast:

(1) 用于类层次结构中基类和派生类之间指针或引用的转换;
上行转换: (把派生类的指针或引用转换成基类表示)是安全的。
下行转换: (把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。
(2) 用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。
(3) 把空指针转换成目标类型的空指针。
(4) 把任何类型的表达式转换成void类型

注意:static_cast不能转换掉expression的const、volatile、或者__unaligned属性

尽量少使用转型操作,尤其是dynamic_cast,耗时较高,会导致性能的下降,尽量使用其他方法替代。

/*基本类型数据转换*/
char a = 'a';
int b = static_cast<char>(a);//正确,将char型数据转换成int型数据

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

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

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


/*类上行和下行转换:*/
class Base
{};

class Derived : public Base
{}

Base* pB = new Base();
if(Derived* pD = static_cast<Derived*>(pB))
{}//下行转换是不安全的(坚决抵制这种方法)

Derived* pD = new Derived();
if(Base* pB = static_cast<Base*>(pD))
{}//上行转换是安全的

 

2、dynamic_cast:

该运算符把expression转换成new_type类型的对象。new_type 必须是类的指针、类的引用或者void*;

如果 new_type 是类指针类型,那么expression也必须是一个指针,如果 new_type 是一个引用,那么 expression 也必须是一个引用。

dynamic_cast运算符可以在执行期决定真正的类型。

如果 downcast 是安全的(也就说,如果基类指针或者引用确实指向一个派生类对象)这个运算符会传回适当转型过的指针。

如果 downcast 不安全,这个运算符会传回空指针(也就是说,基类指针或者引用没有指向一个派生类对象)。

dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。

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

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

/*
  B 要有虚函数,否则会编译出错;static_cast则没有这个限制。
  这是由于运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表中,
  只有定义了虚函数的类才有虚函数表,没有定义虚函数的类是没有虚函数表的。
*/
 class B
 {
    public:
        int num;
        virtual void fun();
 };
 class D:public B
 {
    public:
        char* sz[100];
 };
int main()
{
    B* pb;
    D* pd = dynamic_cast<D*> (pb); 
    return 0;
}

 

标签:函数,int,dynamic,C++,cast,static,指针
From: https://www.cnblogs.com/lyfily-p-7439305/p/17591721.html

相关文章

  • C++ error学习
    转自:https://blog.csdn.net/NiuYoohoo/article/details/849304041、介绍errno是用于错误指示的预处理器宏,数个标准库函数通过写入正整数到errno指示错误。程序启动时errno的值为​0​,而且尽管不管在错误发生与否时,允许写入正整数到errno。2、例子#include<iostrea......
  • C++ 算法进阶系列之再聊聊动态规划的两把刷子
    1.前言递归和动态规划是算法界的两个扛把子,想进入算法之门,则必须理解、掌握这两种算法的本质。一旦参悟透这2种算法的精髓,再加上对树、图等复杂数据结构的深入理解,可以解决大部分的算法问题。本文通过几个典型案例,再次聊聊动态规划算法。其实动态规划算法也就2把刷子。找到......
  • C++程序获取python脚本控制台输出的一种方法
    作者:朱金灿为什么大多数人学不会人工智能编程?>>>  最近要使用C++程序调用python脚本,调用方法是通过启动python进程来调用,其中遇到的一个问题是在C++程序中需要获取python脚本的控制台输出信息。经过摸索使用_popen函数实现了。下面用python脚本和C++调用示例程序来说明。py......
  • VS选择Visual C++中的控制台项目和空项目、Windows桌面应用程序三者之间有什么区别?
    在VisualStudio中创建C/C++项目时,可以选择控制台项目、空项目和Windows桌面应用程序,它们有以下区别:控制台项目(ConsoleApplication):这种项目类型适用于命令行应用程序的开发。它提供一个命令行界面,可以在控制台中进行输入和输出操作,通常用于简单的控制台程序,如计算器、文件......
  • C++运算符重载
    1.概念赋予运算符更多的功能。2.内容赋值运算符+-*/%运算符自增自减运算符输出流运算符的重载<<输入流运算符的重载>>函数调用运算符()下标运算符[]成员访问运算符->,*3.赋值运算符这个一般是用已存在的对象赋值给另一个已存在的对象。//如存在Comp......
  • C++中fork函数的使用及原理
    C++中fork函数的使用及原理,在C++中,fork函数用于创建一个新的进程称为子进程,该进程与原始进程几乎完全相同。fork函数的基本概况fork()函数调用成功之后,会有两个返回值。当前进程,也就是父进程返回子进程的pid,子进程返回0。如果函数调用错误,返回为-1。#include<stdio.h>#include......
  • C++中的exec()函数
    exec()函数在C++中是一个进程控制函数,用于创建新进程执行其他程序或命令行指令。exec()函数可以替换当前进程的代码和数据,创建新的进程运行其他程序。exec()函数有多个版本,例如execl、execv、execle、execve等,根据不同的参数类型和个数来使用。前言fork函数之后,如果想要把子进程换......
  • C++实现简单的ls命令以及原理
    C++实现简单的ls命令及其原理,C++实现ls命令可通过调用系统函数实现读取目录中的文件名和属性,再通过标准输出进行显示。对控制参数的处理一共有7个可选参数,分别是-a、-l、-R、-t、-r、-i、-s,这些参数可以相互自由组合,因此可以设计一种机制,就是直接把它们全部用循环一次性做或运算,......
  • C++实现工资管理中的随机教师信息生成功能
    使用C++实现工资管理中的随机教师信息生成功能,想要做一个教师工资管理系统,就必须得准备好数据,但是这些数据如果用手一行一行地敲,那么工作量是非常大的,因此,我就产生了用C语言实现直接生成大量的教师基本信息的想法,需要的朋友可以参考下。教师的基本信息typedefstructteacher{......
  • 笔记|《面向对象编程技术与方法(C++)》电子工业出版社
    第一章概述C++多态:https://blog.csdn.net/K346K346/article/details/82774937第二章编程基础数据类型枚举:https://www.runoob.com/w3cnote/cpp-enum-intro.html联合:https://www.runoob.com/cprogramming/c-unions.html作用域运算符:c++入门学习篇(1)之::作用域符解析c++条......