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

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

二、转换的本质 派生类可以转换为的本质是: ①为什么派生类可以转换为派生类而来,因此派生类中包含了的方法和成员。...此时可以通过指针或引用指向派生类(相当于将派生类中继承的那部分方法和成员绑定到上了,相当于派生类被截断了),然后就可以将派生类假装是一个对象来使用(调用其中的成员/方法) ②为什么不能转换为派生类...如果一个对象绑定到派生类指针/引用上,此时派生类通过指针/引用访问自己新定义的成员/方法时,发现找不到(因此不能将转换为派生类) 例如:下面B继承于A,子类继承于父,同时为父的成员开辟了空间...此处p2指针的类型为A,因此调用A的getA()函数。又因为b对象使用setA()函数整个继承体系中的a改为了20,因此打印出来的a为20 ?...演示案例② 我们修改演示案例①,上面是指针指向于派生类

1.6K10

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

说明:本来指针是用来指向对象的,如果用它指向派生类对象,则进行指针类型转换,将派生类对象的指针先转换为指针,所以指针指向的是派生类对象中的部分。...虚函数突破了这一限制,在派生类部分中,派生类的虚函数取代了原来的虚函数,因此在使指针指向派生类对象后,调用虚函数时就调用了派生类的虚函数。...但是,继承来的某些成员函数不完全适应派生类的需要,例如在例12.2中,的display函数只输出的数据,而派生类的display函数需要输出派生类的数据。...过去我们曾经使派生类的输出函数的输出函数不同名(display和display1),但如果派生的层次多,就要起许多不同的函数名,很不方便。如果采用同名函数,又会发生同名覆盖。...需要说明;有时在中定义的非虚函数会在派生类中被重新定义(例12.1中的area函数),如果用指针调用该成员函数,则系统会调用对象中部分的成员函数;如果用派生类指针调用该成员函数,则系统会调用派生类对象中的成员函数

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

继承

派生类之间的关系: 派生类对象可以使用(公有的)方法。 指针可以在不进行显示类型转换的情况下指向派生类对象,但只能调用方法。...实现多态公有继承的方法: 在派生类中重新定义的方法。 使用虚方法(虚函数)。 3. 静态联编和动态联编 函数名联编:编译器源代码中的函数调用解释为执行特定的函数代码称为函数名联编。...将派生类引用或指针转换为引用或指针称为向上强制转换,该转换使得公有继承不需要进行显示类型转换。...且该转换是可以传递的,例如A,其派生类AP,AP的派生类APP,则A指针或引用可以指向或引用AP对象和APP对象。 相反的,我们指针或引用转换为派生类指针或引用称为向下强制转换。...因此,如果要重新定义继承的方法,则应确保与原来的原型完全相同,但是如果返回类型是引用或指针,则可以修改为指向派生类的引用或指针,即允许返回类型随类型的变化而变化,这种特性被称为返回类型协变。

68620

C++系列笔记(五)

为什么需要虚构函数 上面的代码如果加入析构函数释放内存,对于使用new在自由储存区中实例化的派生类对象,如果将其赋值给指针,并通过该指针调用delete,将不会调用派生类的析构函数,这可能导致资源未释放...抽象和纯虚函数 不能实例化的被称为抽象,这样的只有一个用途,那就是它派生出其他。在 C++中,要创建抽象,可声明纯虚函数。...这让可指定派生类中方法的名称和特征(Signature),即指定派生类的接口。虽然不能实例化抽象,但可将指针或引用的类型指定为抽象。...如果这些没有采用虚继承,导致二义性。...注意:C++关键字virtual的含义随上下文而异(我想这样做的目的很可能是为了省事),对其含义总结如下: 在函数声明中,virtual意味着当指针指向派生对象时,通过它可调用派生类的相应函数

65530

C++|对象模型|对象模型综述

Bjarne Stoustrup设计了几种方案[LIPP88],第一种存在普通指针,限定了虚表大小,规定值小于128即为虚函数索引。...每次传递这个指针,都必须产生较大的临时对象。 为了减少上述调用成本,VC++引入了vcall thunk,thunk非虚函数地址改为存放指向一小段代码的指针,这一段代码用来选出并调用虚函数。...一个古老的实现方法是,在每一个派生类对象中存放一个虚指针而非传统对象模型中的对象本身,对虚的访问通过指针间接实现,以此实现共享。...对于问题二: 编译器使用拷贝操作获得所有嵌套虚指针存至派生类,以空间换时间,从而解决了固定存取时间的问题。...而在指针调用派生类重写的虚函数时,则需要反过来调整this指针(由编译器插入或者thunk引入),从而正确指向对应的虚表。

63410

C++:46---绝不重新定义继承而来的non-virtual函数

演示案例 当我们使用的引用(或指针)时,我们并不清楚该引用(或指针)所绑定的对象的真实类型,该对象可能是的对象,也可能是派生类的对象。...A,因此调用A的getA()函数 A 20:虽然p2指针指向的类型为B,但是访问规则只与指针/引用的类型有关,而与指针/引用指向的类型无关。...又因为b对象使用setA()函数整个继承体系中的a改为了20,因此打印出来的a为20 静态绑定 当我们调用non-virtual函数时,调用的函数版本与指针的类型有关 例如,上面的pB指针在初始化时,...{ D x; B *pB = &x; pB->mf(); //调用D::mf() D *pD = &x; pD->mf(); //调用D::mf() return 0; } 三、为什么不建议派生类隐藏的...如果: 我们在派生类中隐藏了的non-virtual函数,那么派生类就会产生行为上的不一致,is-a关系就消失了 如果想要表现出派生类的不同,那么应该函数声明为virtual(其中虚析构函数是一个例子

45120

EasyC++84,私有继承(二)

访问方法 我们知道,在私有继承时,的公有对象以及保护对象会变成派生类的私有对象。我们可以在派生类方法当中使用它,但无法通过派生类对象直接调用,但无法访问的私有方法和对象。...这个概念我们很好理解,但具体到实现上,我们如何在派生类的方法当中调用的公有或者保护方法呢? 比如,在之前的声明当中我们声明了一个Average方法,用来计算学生考试成绩的平均分。...const string& Student::Name() const { return (const string&) *this; } 因为Studentstring中派生而来,所以我们是可以...访问的友元 方法和对象都好办,但友元怎么办呢?因为友元函数并不属于,所以无法通过名或者解析运算符搞定。针对这种情况,我们只能取巧,通过显式地对派生类进行类型转换实现。...引用不会自动发生转换,是因为在私有继承当中,在不进行显式类型转换的情况下,不能将派生类的引用或指针赋给的引用或指针。 那么问题来了,如果我们使用的是公有继承,那么是不是就可以了呢?

36810

【c++】继承学习(一):继承机制与派生类转换

是一个一般的,它定义了一种通用的数据类型和方法,这些可以被其他继承。...无法访问,因为_No是Student特有的成员,即使它实际上存在于sobj中 即使我们通过引用或指针操作对象,派生类对象的完整信息(所有成员变量和函数)仍然都在内存中,没有丢失。...使用引用和指针时不会发生切片 对象切片的问题仅在派生类对象被赋值给另一个类型的对象时才会发生,比如当派生类对象被传值给一个对象的函数参数,或者通过赋值构造一个新的对象。...在使用引用或指针时,这种情况并不会发生 对象不能赋值给派生类对象 指针或者引用可以通过强制类型转换赋值给派生类指针或者引用。但是必须是指针是指向派生类对象时才是安全的。...; } protected: int _num = 999; // 学号 }; void Test() { Student s1; s1.Print(); }; 这段代码展示了成员隐藏,以及如何在派生类中访问的被隐藏成员的概念

28810

C++ 一篇搞懂继承的常见特性

派生类派生类是通过对进行修改和扩充得到的,在派生类中,可以扩充新的成员变量和成员函数派生类拥有的全部成员函数和成员变量,不论是private、protected、public。...---- — 5 — 派生类的构造函数 通常在初始化派生类构造函数时,派生类构造函数是要实现初始化构造函数的。...那么如何在派生类构造函数里初始化构造函数呢?...第33-36行代码是正确派生类构造函数初始化构造函数的方式,通过调用构造函数来初始化,在执行一个派生类的构造函数 之前,总是先执行的构造函数。...从上面的例子中我们也得知构造派生对象前,是先构造对象,那么在析构的时候依然依据“先构造,后初始化”的原则,所以派生类析构时,会先执行派生类析构函数,再执行析构函数

54830

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

当使用指针访问虚成员变量时,由于指针可以是指向派生类实例的指针,所以,编译器不能根据声明的指针类型计算偏移,而必须找到另一种间接的方法,派生类指针计算虚的位置。...在VC++ 中,对每个继承自虚实例,增加一个隐藏的“虚指针”(vbptr) 成员变量,从而达到间接计算虚位置的目的。...况且,这种实现方式还有一个大弊端:多个虚派生时,实例占用更多的内存空间;获取虚的虚的地址时,需要多次使用指针,从而效率较低等等。...4 多重继承下的虚函数 如果多个有虚函数继承,一个实例就有可能包含多个vfptr。考虑如下的R和S: ?...MSC++的实现不是这样,MSC++有意S::rvf编译为接受一个指向S中嵌套的R实例,而非指向S实例的指针(我们称这种行为是“给派生类指针类型与该虚函数第一次被引入时接受的指针类型相同”)。

1.2K20

后台开发:核心技术与应用实践 -- C++

同样a[5] 改为a[6]依旧占用24byte,但是改为a[7]占用32byte。...派生类构造函数必须对这3成员进行初始化,其执行顺序是这样的: 先调用构造函数; 再调用子对象的构造函数; 最后调用派生类的构造函数体 当派生类有多个时,处于同一层次的各个的构造函数的调用顺序取决于定义派生类时声明的顺序...在派生时,派生类是不能继承的析构函数的,也需要通过派生类的析构函数去调用的析构函数。...而 虚函数 的作用是允许在派生类中重新定义与类同名的函数,并且可以通过指针或引用来访问派生类中的同名函数。...虚函数的声明方式: virtual 返回类型 函数名(); 当把某个成员函数声明为虚函数后,就允许在其派生类中对该函数重新定义,赋予它新的功能,且可以通过指向指针指向同一族中不同类的对象,从而调用其中的同名函数

1.3K10

《C++面向对象程序设计》✍千处细节、万字总结(建议收藏)「建议收藏」

函数参数也可以用const说明,用于保证实参在该函数不被改动。 void型指针 void通常表示无值,但void作为指针的类型时,它却表示不确定的类型。...因为使用对象引用作为函数参数不但具有用对象指针函数参数的优点,而且用对象引用作函数参数简单、更直接。...,可以在派生类完成以下几种功能: 可以增加新的数据成员和成员函数 可以对的成员进行重定义 可以改变成员在派生类中的访问属性 成员在派生类中的访问属性 派生类可以继承中除了构造函数与析构函数之外的成员...在C++中,可以通过这个公共的声明为虚来解决这个问题。这就要求base派生新时,使用关键字virtualbase声明为虚。...若虚由非虚派生而来,则仍然先调用构造函数,再调用派生类的构造函数。 ~ 5.6 赋值兼容规则 在一定条件下,不同类型的数据之间可以进行类型转换,可以整型数据赋值给双精度型变量。

3.1K40

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

我们很多时候希望的是我们通过指针指向派生类,然后可以动态调用派生类函数,这时我们可以的对应函数写为虚(virtual)函数来实现,此时发生的称为动态绑定 通过在声明语句前加上关键字virtual...实现虚函数,virtual只能添加在函数声明前。...,这一项决定的是派生类对继承来的成员对外表现出的最高权限,也就是这一项并不会影响派生类内部的使用,但是一旦外部想调用派生类来使用成员: 如果此时访问说明符为public,则成员对外表现的权限 如果此时为...为了规范和可读性,最好不要利用默认控制符,显式说明比较清晰 15.6 继承中的作用域 中的名字查找是到外查找的,当派生类中无法找到时,就会往直接查找,以此类推 名称查找是根据编译时的目标的静态类型进行查找的...,对于实现的内容我们一样可以使用=default简化 如果的析构函数不是虚函数,则delete一个指向派生类对象的指针产生未定义的行为 如果定义了虚析构函数,则一样的合成移动操作将被阻止 派生类的析构函数和以往一样是空函数

50520

【编程基础】如何赢得C++面试

4.子类析构时要调用父的析构函数吗? 析构函数调用的次序是先派生类的析构后的析构,也就是说在的的析构调用的时候,派生类的信息已经全部销毁了。...定义一个对象时先调用的构造函数、然后调用派生类的构造函数;析构的时候恰好相反:先调用派生类的析构函数、然后调用的析构函数 5.C++中的class和struct的区别 语法上,在C++中(只讨论...b.覆盖是指派生类函数覆盖函数,特征是: (1)不同的范围(分别位于派生类); (2)函数名字相同; (3)参数相同; (4)函数必须有virtual关键字。 c....“隐藏”是指派生类函数屏蔽了与其同名的函数,规则如下: (1)如果派生类函数函数同名,但是参数不同。此时,不论有无virtual关键字,函数将被隐藏(注意别与重载混淆)。...(2)如果派生类函数函数同名,并且参数也相同,但是函数没有virtual关键字。

1.4K70

硬核 | C++ 基础大全

要注意,重写和被重写的函数是在不同的当中的,重写函数的访问修饰符是可以不同的,尽管 virtual 中是 private 的,派生类中重写可以改为 public。...大多数编译器中,参数是右向左入栈(原因在于采用这种顺序,是为了让程序员在使用C/C++的“函数参数长度可变”这个特性时方便。...如果对象类型是派生类,就调用派生类函数,如果是,就调用函数。...),仅执行的析构,派生类的自身内容无法被析构,造成内存泄漏。...; 之间应满足子类型关系,通常表现为一个另一个公有派生而来; 必须先使用指针指向子类型的对象,然后直接或间接使用指针调用虚函数; 什么是的继承?

1.2K10

《C++Primer》第十五章 面向对象程序设计

如果想使用其他的构造函数,我们需要以名加圆括号的实参列表的形式为构造函数提供初始值。这些实参用于帮助编译器到底应该选择哪个构造函数来初始化派生类对象的部分。...有一点需要注意的是,即使一个指针或者引用绑定在一个派生类对象上,我们也不能执行派生类的转换: Bulk_quote bulk; Quote *itemP = &bulk; //...3.4 存在继承关系的类型之间的转换规则 要想理解在具有继承关系的之间发生的类型转换,有三点特别重要: 派生类的类型转换只对指针或者引用类型有效 派生类不存在隐式类型转换 和任何其他成员一样...如果一个名字在派生类的作用域无法正确解析,那么编译器继续在外层的作用域中寻找该名字的定义。...一往常,名字查找先于类型检查 声明在内层作用域的函数并不会重载声明在外层作用域的函数。因此定义派生类中的函数也不会重载其的成员。

1.2K20

如何把CPP源程序改写成C语言?

下面对C++的一些特性,以及如何在c里实现或者替代,作一些初步的探讨: 说明: 函数Ixx为xx的构造函数的实现。 原的成员函数改为前缀为结构体名+‘_’的函数。...而函数前如果有virture,inline等修饰符也要去掉,函数void funca(int a);改为void (*funca)(struct B *p,int a);大家可以看到函数指针的原型里加了一个指针...之所以所有的struct都用指针U是基于如下情况: 如果子类指针赋给指针指针在释放的时候不必考虑调用哪个函数名的析构函数,只需调用成员函数U即可。...除了的构造函数改为子类构造函数名外,不可以定义的部分作其他改动。并在构造函数里调用的构造函数,然后如果子类覆盖了函数,则要把该函数指针重定向到子类函数。...多继承也是可以改的,多个的成员全部拷到子类里,遇到重复的成员名,则在前面加上前缀来区别,当然这个指的是之间有相同的,如果是派生类之间有重名的,则会覆盖

2.1K20

从零开始学C++之继承(二):继承与构造函数派生类的转换

输出可以看出: 派生类对象的构造次序: 先调用对象成员的构造函数,接着是的构造函数,然后是派生类的对象成员的构造函数,最后是派生类自身的构造函数。...初始化列表参数多个且其中有调用构造函数时,先执行构造函数最远的开始,如果多重继承则按继承的顺序);其他对象成员若不止一个,则按定义的顺序构造,与初始化列表顺序无关。...四、派生类的转换 当派生类以public方式继承时,编译器可自动执行的转换(向上转型 upcasting 安全转换) 派生类对象指针自动转化为对象指针 派生类对象引用自动转化为对象引用...将派生类对象看成对象     //pm = &e1; // 对象指针无法转化为派生类对象指针。...无法对象看成是派生类对象     e1 = m1;    // 派生类对象可以转化为对象。将派生类对象看成对象     // 会产生对象切割(派生类特有成员消失)。

1.5K00

【C++】继承

派生类对象可以直接赋值给对象/指针/引用,的对象可直接得到派生类对象中成员的那一部分,而指针或引用是直接指向或者引用到派生类对象中成员那一部分。 2....拷贝构造函数与构造不同,必须在派生类的拷贝构造的初始化列表处显示调用的拷贝构造,完成成员的复制。在传参时有人可能会有疑问,调用的拷贝构造该如何子类中成员提取出来呢?...虚拟继承后,BC派生类中不再存储虚成员,改为存储虚指针,虚指针指向的一张表叫做虚表,这个表中存储了派生类成员到虚成员的地址偏移量,通过偏移量就可以找到虚成员的内存地址。...而这个内存地址只有一份,所以这就解决了数据冗余的问题,因为内存中不再像原来一样,派生类中分别存储虚成员导致数据冗余,而是仅仅只存一份虚成员,派生类改为存储虚指针。 4....腰部的派生类存虚指针干嘛呢还。 5.

65210
领券