首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

C++:43---派生类转换、静态动态变量

二、转换本质 派生类可以转换为本质是: ①为什么派生类可以转换为派生类而来,因此派生类中包含了方法和成员。...此时可以通过指针或引用指向派生类(相当于将派生类中继承那部分方法和成员绑定到上了,相当于派生类被截断了),然后就可以将派生类假装是一个对象来使用(调用其中成员/方法) ②为什么不能转换为派生类...如果一个对象绑定到派生类指针/引用上,此时派生类通过指针/引用访问自己新定义成员/方法时,发现找不到(因此不能将换为派生类) 例如:下面B继承于A,子类继承于父,同时为父成员开辟了空间...//假设B公有继承于A A *a; B b; a = &b; //将派生类换为,正确 B *p = a; //再转换为派生类,错误 五、静态类型/动态类型 在上面我们介绍过,指针或引用可以指向对象也可以指向派生类对象...演示案例② 我们修改演示案例①,上面是指针指向派生类

1.6K10
您找到你想要的搜索结果了吗?
是的
没有找到

继承

派生类之间关系: 派生类对象可以使用(公有的)方法指针可以在不进行显示类型转换情况下指向派生类对象,但只能调用方法。...将派生类引用或指针换为引用或指针称为向上强制转换,该转换使得公有继承不需要进行显示类型转换。...且该转换是可以传递,例如A,其派生类AP,AP派生类APP,则A指针或引用可以指向或引用AP对象和APP对象。 相反,我们指针或引用转换为派生类指针或引用称为向下强制转换。...虚函数表存储了为对象进行声明虚函数地址。通常情况下,对象包含一个指向该类中虚函数表指针。...因此,如果要重新定义继承方法,则应确保与原来原型完全相同,但是如果返回类型是引用或指针,则可以修改为指向派生类引用或指针,即允许返回类型随类型变化而变化,这种特性被称为返回类型协变。

68220

c++类型转换与RTTI运行阶段类型识别

我们都知道C++完全兼容C语言,C语言转换方式很简单,可以在任意类型之间转换,但这也恰恰是缺点,因为极其不安全,可能不经意间指向const对象指针转换成非const对象指针,可能将对象指针转成了派生类对象指针...另外,static_cast还可以将派生类指针换为指针,而且一定条件下还能将指针换为派生类指针,且不会报错,只是一些只有派生类才会有的函数、成员变量,转换过来指针也不会有。...dynamic_cast,一般只用于派生类之间转换,而且只能用于派生类指针转换成指针,不能反向转换。...在多态中,比如上面代码中有Test和TestDerived,现在有一个Test指针,但不知道这个指针究竟指向还是派生类,怎么知道指针指向哪种对象呢?...目前c++中有3个支持RTTI元素:dynamic_cast,一个指向指针来生成一个指向派生类指针,否则,该运算符返回空指针typeid,返回一个指针对象类型值type_info,结构存储了有关特定类型信息

14800

C++中类型转换

/引用转换为子类对象指针或引用(动态转换) 向上转型:子类对象指针/引用->父指针/引用(不需要转换,赋值兼容规则) 向下转型:父对象指针/引用->子类指针/引用(用dynamic_cast转型是安全...static_cast,命名上理解是静态类型转换 使用场景: 用于层次结构中派生类之间指针或引用转换 注意: 上行转换(派生类—->)是安全;下行转换(—->派生类)由于没有动态类型检查...必须要有虚函数 对于下行转换,dynamic_cast是安全(当类型不一致时,转换过来是空指针),而static_cast是不安全(当类型不一致时,转换过来是错误意义指针,可能造成踩内存...,非法访问等各种问题) const_cast,字面上理解就是去const属性 使用场景: 常量指针换为非常量指针,并且仍然指向原来对象 常量引用被转换为非常量引用,并且仍然指向原来对象...使用场景: 不到万不得已,不用使用这个转换符,高危操作 使用特点: reinterpret_cast可以整型转换为指针,也可以把指针换为数组 reinterpret_cast可以在指针和引用里进行肆无忌惮转换

1.9K20

【笔记】《C++Primer》—— 第15章:面向对象程序设计

派生类在继承函数时,如果需要覆盖(override)继承函数,那就要在派生类中将完全相同函数声明出来 我们可以一个派生类对象转换为对象,此时派生类独有的部分将被截断,其部分被处理而派生类部分被忽略...我们很多时候希望是我们通过指针指向派生类,然后可以动态调用派生类函数,这时我们可以对应函数写为虚(virtual)函数来实现,此时发生称为动态绑定 通过在声明语句前加上关键字virtual...每个都会继承其直接成员,然后转换为自己成员继续派生下去,因此最后一层派生包含所有成员 有时候我们不希望其他继承某个,可以在声明后加上final表示无法继续派生 智能指针也支持派生到类型转换...这里有一个特别的,即便处理指针,此指针指向派生类,我们也不能隐式转换到这个派生类,如果中含有虚函数,我们可用用dynamic_cast强制转换 15.3 虚函数 通过对指针或引用来调用虚函数时会出现动态绑定...,对于实现内容我们一样可以使用=default简化 如果析构函数不是虚函数,则delete一个指向派生类对象指针产生未定义行为 如果定义了虚析构函数,则一样合成移动操作将被阻止 派生类析构函数和以往一样是空函数

50120

C++:29 --- C++继承关系下内存布局(下)

当使用指针访问虚成员变量时,由于指针可以是指向派生类实例指针,所以,编译器不能根据声明指针类型计算偏移,而必须找到另一种间接方法派生类指针计算虚位置。...该变量指向一个全共享偏移量表,表中项目记录了对于该类 而言,“虚指针”与虚之间偏移量。 其它实现方式中,有一种是在派生类中使用指针成员变量。...这些指针成员变量指向派生类,每个虚一个指针。这种方式优点是:获取虚地址时,所用代码比较少。然而,编译器优化代码时通常都可以采取措施避免重复计算虚地址。...况且,这种实现方式还有一个大弊端:多个虚派生时,实例占用更多内存空间;获取虚地址时,需要多次使用指针,从而效率较低等等。...MSC++实现不是这样,MSC++有意S::rvf编译为接受一个指向S中嵌套R实例,而非指向S实例指针(我们称这种行为是“给派生类指针类型与该虚函数第一次被引入时接受指针类型相同”)。

1.1K20

C++中四种类型转换运算符

A*转换为int*,使用指针直接访问 private 成员刺穿了一个封装性,更好办法是让提供 get/set 函数,间接地访问成员变量。...pa 是A*类型指针,当 pa 指向 A 类型对象时,向下转型失败,pa 不能转换为B*或C*类型。当 pa 指向 D 类型对象时,向下转型成功,pa 可以转换为B*或C*类型。...从表面上看起来 dynamic_cast 确实能够向下转型,本例也很好地证明了这一点:B 和 C 都是 A 派生类,我们成功地 pa A 类型指针转换成了 B 和 C 类型指针。...但是本质上讲,dynamic_cast 还是只允许向上转型,因为它只会向上遍历继承链。造成这种假象根本原因在于,派生类对象可以用任何一个指针指向它,这样做始终是安全。...本例中情况②,pa 指向对象是 D 类型,pa、pb、pc 都是 D 指针,所以它们都可以指向 D 类型对象,dynamic_cast 只是让不同指针指向同一个派生类对象罢了。

21020

RTTI和类型转换运算符

1.1 RTTI三个元素 由于只有包含虚函数层次结构,才能将派生类对象地址赋给指针,因此RTTI只适用包含虚函数。...dynamic_cast运算符将使用一个指向指针来生成一个指向派生类指针,否则,该运算符返回0—空指针。 typied运算符返回一个指出对象类型值。...主要在以下几种场合中使用: 用于层次结构中,和子类之间指针和引用转换;当进行上行转换(把派生类指针或引用转换成表示),这种转换是安全;当进行下行转换(把指针或引用转换成派生类表示)...reinterpret_cast 运算符并不会改变括号中运算对象值,而是对该对象位模式上进行重新解释。它主要用于一种数据类型从一种类型转换为另一种类型。...例如,它可以一个指针转换成一个整数,也可以一个整数转换成一个指针,然而,其并不支持所有类型转换,例如,可以指针类型转换为足以存储指针表示整形,但不能将指针换为更小整形或浮点型。

57130

C++之虚函数作用和使用方法

说明:本来指针是用来指向对象,如果用它指向派生类对象,则进行指针类型转换,将派生类对象指针先转换为指针,所以指针指向派生类对象中部分。...虚函数突破了这一限制,在派生类部分中,派生类虚函数取代了原来虚函数,因此在使指针指向派生类对象后,调用虚函数时就调用了派生类虚函数。...但是,继承来某些成员函数不完全适应派生类需要,例如在例12.2中,display函数只输出数据,而派生类display函数需要输出派生类数据。...如果在派生类中没有对虚函数重新定义,则派生类简单地继承其直接虚函数。 定义一个指向对象指针变量,并使它指向同一族中需要调用该函数对象。...通过该指针变量调用此虚函数,此时调用就是指针变量指向对象同名函数。 通过虚函数与指向对象指针变量配合使用,就能方便地调用同一族中不同类同名函数,只要先用指针指向即可。

1.3K80

【笔记】《C++Primer》—— 第18章:用于大型程序工具

都能正常处理异常 异常对象类型是由表达式静态类型决定,也就是我们抛出指向派生类指针时,该派生类将被切去一部分 catch语句括号内容是异常声明,类似函数形参列表,用起来也很相近,和之前一样如果我们想要...catch捕获异常忽略掉 catch只允许最基础转换,包括常量改变,派生向,数组指针,函数指针四种,其他类型转换都不支持 有时候我们发现单个catch无法完全处理好异常时,我们用一个空throw...,这都可能引起混乱 18.3 多重继承与虚继承 C++支持多重继承(很多其他语言不支持这一特性),方法就是继承列表多些几个,因此我们可以多个直接产生派生类,这个派生类会继承所有父属性...要注意构造顺序是与派生列表中出现顺序一致,与派生类参数顺序无关 C11中允许派生类多个中继承构造函数,但是如果多个构造函数都相同的话产生错误,此时派生类应该自己定义一个构造函数来覆盖它们...析构函数调用顺序与构造顺序相反特性仍在 合成拷贝移动等操作规则也与之前一致 我们可以用指针指向派生类对象,但是调用对应函数时候编译器不会觉得不同方向转换有好坏之分,因此当有多个接受不同参数但名字相同函数时

93620

《逆袭进大厂》第三弹之C++提高篇79问79答

1) 向上类型转换 将派生类指针或引用转换为指针或引用被称为向上类型转换,向上类型转换会自动进行,而且向上类型转换是安全。...2) 向下类型转换 指针或引用转换为派生类指针或引用被称为向下类型转换,向下类型转换不会自动进行,因为一个对应几个派生类,所以向下类型转换时不知道对应哪个派生类,所以在向下类型转换时必须加动态类型识别技术...2) 多重继承优点很明显,就是对象可以调用多个接口; 3) 如果派生类所继承多个有相同,而派生类对象需要调用这个祖先接口方法,就会容易出现二义性 4) 加上全局符确定调用哪一份拷贝...; 2) 没有任何构造函数派生自一个带有默认构造函数,那么需要为该派生类合成一个构造函数,只有这样构造函数才能被调用; 3) 带有虚函数,虚函数引入需要进入虚表,指向虚表指针...虚函数是为了实现动态编联产生,目的是通过类型指针指向不同对象时,自动调用相应、和类同名函数(使用同一种调用形式,既能调用派生类又能调用同名函数)。

2.2K30

C++ Primer 学习笔记_87_用于大型程序工具 –异常处理

相反,假设抛出一个数组,被抛出对象转换为指向数组首元素指针,相似的,假设抛出一个函数,函数转换为指向该函数指针。...假设该指针是一个指向派生类对象类型指针,则那个对象将被切割,仅仅抛出部分。 谨记:抛出指向局部对象指针总是错误,因此,在抛出指针时候,必须确定进入处理代码时指针指向对象存在。...也就是说,非const对象 throw能够与指定接受const引用 catch匹配。 2)同意派生类型型到类型转换。...3)数组转换为指向数组类型指针,函数转换为指向函数类型适当指针。 在查找匹配catch时候,不同意其它转换。...假设被抛出异常对象是派生类类型,但由接受类型catch处理,那么,catch不能使用派生类特有的不论什么成员。

69010

java中downcast向下转型到底有什么用? 举例说明!

当一个方法只有子类才有,马克-to-win:不是说和子类都有,开始时又是指针指向派生类,这时就需要downcast, see the following example. after you cast...SuperClassM_t_w() {         a = 5;     }     public void printAsuper() {         System.out.println("父中..., default constructor. */         SuperClassM_t_w s1 = new SubClass(10);         s1.printAsuper();//指针指向派生类时...,马克-to-win: 可以用指针调用仅有的方法, 但不能调用子类仅有的方法。...必须向下强一下。         // s1.printA();错误 /* 我们不能去掉下面的话,因为SuperClassM_t_w没有printA方法

67060

浅谈C++多态性

最常见使用方法就是声明基指针,利用该指针指向随意一个子类对象,调用对应虚函数,能够依据指向子类不同而实现不同方法。...假设没有使用虚函数的话,即没有利用C++多态性,则利用指针调用对应函数时候,总被限制在函数本身,而无法调用到子类中被重写过函数。...p->foo()和p->fuu()则是指针指向子类对象,正式体现多态使用方法,p->foo()因为指针是个指针指向是一个固定偏移量函数,因此此时指向就仅仅能是foo()函数代码了...这是一个用子类指针指向一个强制转换为子类地址对象。结果,这两句调用输出结果是3,2。   ...并非非常理解这样使用方法原理上来解释,因为B是子类指针,尽管被赋予了对象地址,可是ptr->foo()在调用时候,因为地址偏移量固定,偏移量是子类对象偏移量,于是即使在指向了一个对象情况下

35610

【笔记】《C++Primer》—— 第三部分:设计者工具

但我们可以const左值引用绑定到右值上 移动构造具体写法类似拷贝构造,但是构造参数是自己类型右值引用,为了完成移动构造,我们需要保证移动后源对象处于可以无害销毁状态,源对象指针不再指向原先资源...重载 overload,指对一个同名方法进行了几种不同参数实现 可以一个派生类对象转换为对象,此时派生类独有的部分将被截断,其部分被处理而派生类部分被忽略 有时我们不希望派生类独有的部分被截断则需要使用指针来调用重载函数或使用指针所指成员...我们很多时候希望是我们通过指针指向派生类,然后可以动态调用派生类函数,这时我们可以对应函数写为虚(virtual)函数来实现,此时发生称为动态绑定 派生类可以继承多个,称为多继承...每次继承一个就会在内存中生成一个子对象,存放了成员,也正是因为这个原因派生类可以转换为 派生类构造函数需要负责所有成员初始化,尽管派生类也可以初始化继承来成员,但是这不符合通常编码思路...因此除了重载虚函数外最好不要让名称同名 派生类可以覆盖重载函数,但是如果派生类希望重载几个函数都在派生类中可见的话:一种方法是不覆盖任何一个重载函数或所有重载函数都进行一次覆盖;另一种方法是为需要重载函数名使用

1.7K10

C++基础-多态

这种情况未启用多态机制 如果 Swim() 是虚函数,那么运行时会根据引用(或指针)指向具体对象,调用对象所属方法。...若指向派生类对象则调用派生类方法,若指向对象则调用方法。...这种情况使用了多态机制 使用指针或引用指向派生类对象,运行时调用对象所属(具有继承层次关系派生类)中方法,这就是多态。...,delete 派生类析构方式来析构此指针(调用派生类析构函数和析构函数)。...可见使用虚继承可以解决多继承时菱形问题,确保 在继承层次结构中,继承多个同一个派生而来时,如果这些没有采用虚继承,导致二义性。

83020

C++关键知识点梳理

左值引用&右值引用左值引用:常规引用,可支持取地址运算符&获取内存地址;右值引用:右值是临时对象、字面量等表达式,右值引用解决临时对象或函数返回值给左值对象时深度拷贝;std::move:输入左值或右值转换为右值引用类型临终值...oop封装C++中封装通过对访问权限实现,客观事物抽象成数据成员和方法,并通过public,protected,private三种访问权限控制其他对象对访问和继承。...每个虚继承子类都有一个虚指针(占用一个指针存储空间,4字节)和虚表(不占用对象存储空间)当派生类重新定义虚函数时,则将派生类虚函数地址添加到虚函数表中。...当一个指针指向一个派生类对象时,虚函数表指针指向派生类对象虚函数表。当调用虚函数时,由于派生类对象重写了派生类对应虚函数表项,在调用时会调用派生类虚函数,从而产生多态。...虚析构函数:为了防止delete指向派生类对象指针时只调用析构函数引起内存泄漏using namespace std;class Base {public: virtual ~ Base

91830
领券