1.通过对象直接调用成员函数时,始终默认使用该对象的类的成员函数(除非用::显示指定类名)。
2.通过指向对象的指针或引用调用成员函数时:如果该函数是实函数,则调用该指针或引用的类的成员函数;如果该函数是虚函数,则调用该指针或引用指向的对象的类的成员函数。
3.基类析构函数在此情况下必须为虚函数(此时,其派生类的析构函数也将是虚函数):用new来创建派生类对象,并且delete时使用的指针为基类的指针。若为实析构函数,则派生类部分的成员将不会被析构。
4.若未定义复制构造函数,不要将一个派生类对象强制类型转换为基类对象。因为若未显式定义复制构造函数,则编译器会生成一个默认的复制构造函数。然而这个默认的复制构造函数将不会做你希望做的其他的事,如:如果要在构造函数中维护一个类对象的计数器,则这个函数不会导致计数器增加;如果要在构造函数中new一个对象,则这个函数也不会new该有的对象。这个默认的复制构造函数进行的是浅拷贝,使用的成员都是原来的对象的。因此这个临时对象在析构时,delete的是原来的对象new出来的对象;而原来的对象在析构时将再次delete这个对象;这属于未定义行为,可能引起程序崩溃。并且,即使在析构函数中,在delete这个对象后,将指向这个对象的指针赋值为NULL也无效;因为更改的是临时对象的指针,而原对象的指针仍指向那个被delete了的对象。
关于第4点的结论,我实际上是写了另一个测试代码证明的。不过那个测试代码在最后一次测试时被我改得太乱了,就不给出了。有兴趣的可以将A1和A2类添加静态的对象计数器、对象指针和复制构造函数,再自己去研究。我在VC++6.0 SP6上测试时,debug和release模式下运行状态居然不同(前者崩溃,后者看上去正常)。然而我一直没太多时间好好研究它,问了好多人却没人给出正确回答。最后我只好自己跟踪反汇编代码了。能得出上述的结论,还得感谢VC++的调试器。
附:原理阐述
c++的编译器是怎么识别这个指针指向派生类的对象的?例如:class A { int i; int j; virtual void function(){ cout<<"this is class a"<<endl; }};
class B :public A{ int k; void function() { cout<<"this is class b"<<endl; }};
void main(){ A* pa; A a; pa=&a; pa->function(); B b; pa=&b; pa->function();}类A的对象块的空间大小是和类B的对象块的大小一样吗?
类A的对象块的空间大小和类B的对象块的空间大小不一样。就此代码,32位环境中,A的对象12字节(两个int一个虚表指针),B的对象16字节(三个int一个虚表指针)。
把&b赋值给pa之前,b的空间已经分配好了16字节。所谓“把&b赋值给pa”,只不过是把那16字节的首地址保存在pa中,所以把&b赋值给pa之后,pa指向的空间大小是16字节,而不是12字节。只是因为pa的类型为A*,所以用pa->的形式只可以访问到b中属于从A继承的部分,而不能访问到B增加的部分。
通过指针访问成员实际上要计算一个该成员在对象中的偏移。然后用指针中的地址加上这个偏移就访问到了成员。 虚函数的实质是每个对象中有一个指针 ,指向一个表,表中依次存放了虚函数的地址。这个表我们叫他虚表。当我们用pa->function();这样的形式调用一个虚函数,编译器实际上隐式做了一些转换,先通过虚表指针找到虚表,再在虚表中找到虚函数指针,最后通过虚函数指针调用虚函数。
一个虚函数指针在基类的虚表中的位置和 在派生类的虚表中的位置是相同的。派生类改写一个虚函数意味着增加一段函数代码,同时派生类的虚表中对应的虚函数指针更改为指向新增加的代码。
指针的类型只是决定了访问成员时计算偏移的方式和大小,而指针不管指向基类还是派生类,调用一个虚函数所需要的偏移是一样的,只是内容不一样,从而导致不同的形为。
您还没有登录,请您登录后再发表评论
6个不同C++实现继承与多态实验,附截图。利用虚基类解决二义性问题。动态多态性概念及掌握使用方法。虚函数的使用方法
C++实现多态的职工管理系统。涉及抽象类,继承,多态等知识。实现的功能如下: 公司中职工分为三类:普通员工、经理、老板; 显示信息时需要显示:职工编号,职工姓名,职工岗位,职责; 普通员工的职责:完成经理...
C++虚拟与多态学习,帮你更深刻的理解虚拟与多态,更深刻的理解C++。技术更上一层楼
C++多态技术的实现和反思 C++多态技术的实现和反思
利用C++及其多态实现的职工管理系统
C++多态的实现,详细讲述了C++中实现多态的过程,教会怎样运用多态解决实际问题。
C语言实现C++多态,主要是思想很重要!
C++实现的一个继承与多态的例子,内容详细且易懂
通过两个程序代码例子彻底理解什么是多态,什么是虚函数;
C++的多态是通过虚表指针来实现的。但是在构造和析构函数中调用虚函数,情况如何呢?是否还能实现多态呢?本文档从内存角度揭示了这其中的多态实现过程。
这是C++编写的体现多态的程序,是在C++类里通过继承和派生来实现的,比较简单
函数的重载:根据函数调用时所给的参数类型和数量不一样,在程序运行前就知道应该调用哪一个函数。 运算符的重载:根据运算对象的不同在编译时就可以确定执行什么样的结果
C++多态虚函数表,C++多态虚函数表,希望大家共同交流学习。
c++多态实现原理分析1
c++多态实现及原理1
笔者校招面试时被问到了著名问题「C++ 与 Java 如何实现多态」,然后不幸翻车。过于著名反而没有去准备,只知道跟虚函数表有关。面试之后比较了 C++ 和 Java 多态的实现的异同,一并记录在这里。 C++ 多态的虚指针...
c++多态类动物的叫声
C++ 中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技 术可以让父类的指针有“多种形态”,这是一种泛型技术...
虚函数是C++中用于实现多态(polymorphism)的机制。核心理念就是通过基类访问派生类定义的函数。
相关推荐
6个不同C++实现继承与多态实验,附截图。利用虚基类解决二义性问题。动态多态性概念及掌握使用方法。虚函数的使用方法
C++实现多态的职工管理系统。涉及抽象类,继承,多态等知识。实现的功能如下: 公司中职工分为三类:普通员工、经理、老板; 显示信息时需要显示:职工编号,职工姓名,职工岗位,职责; 普通员工的职责:完成经理...
C++虚拟与多态学习,帮你更深刻的理解虚拟与多态,更深刻的理解C++。技术更上一层楼
C++多态技术的实现和反思 C++多态技术的实现和反思
利用C++及其多态实现的职工管理系统
C++多态的实现,详细讲述了C++中实现多态的过程,教会怎样运用多态解决实际问题。
C语言实现C++多态,主要是思想很重要!
C++实现的一个继承与多态的例子,内容详细且易懂
通过两个程序代码例子彻底理解什么是多态,什么是虚函数;
C++的多态是通过虚表指针来实现的。但是在构造和析构函数中调用虚函数,情况如何呢?是否还能实现多态呢?本文档从内存角度揭示了这其中的多态实现过程。
这是C++编写的体现多态的程序,是在C++类里通过继承和派生来实现的,比较简单
函数的重载:根据函数调用时所给的参数类型和数量不一样,在程序运行前就知道应该调用哪一个函数。 运算符的重载:根据运算对象的不同在编译时就可以确定执行什么样的结果
C++多态虚函数表,C++多态虚函数表,希望大家共同交流学习。
c++多态实现原理分析1
c++多态实现及原理1
笔者校招面试时被问到了著名问题「C++ 与 Java 如何实现多态」,然后不幸翻车。过于著名反而没有去准备,只知道跟虚函数表有关。面试之后比较了 C++ 和 Java 多态的实现的异同,一并记录在这里。 C++ 多态的虚指针...
c++多态类动物的叫声
C++ 中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技 术可以让父类的指针有“多种形态”,这是一种泛型技术...
虚函数是C++中用于实现多态(polymorphism)的机制。核心理念就是通过基类访问派生类定义的函数。