`
wangyanlong0107
  • 浏览: 502709 次
  • 性别: Icon_minigender_1
  • 来自: 沈阳
社区版块
存档分类
最新评论

【转】 多态与虚函数

    博客分类:
  • c++
 
阅读更多

多态与虚函数

                
                
1.多态性
多态的概念:
l         在面向对象的概念中,多态性是指不同对象收到相同消息时,根据对象类不同产生不同的动作。
 
C++允许程序员发送相同消息到不同的相关对象,而由对象决定如何完成该动作,并且支持软件选择实现决策的时间。其中,运行时的多态是面向对象的程序设计语言所独有的。有人还认为,只有与动态联编相结合的多态才是真正的面向对象的多态。
 
多态的特点:
l          提供了把接口与实现分开的另一种方法;
l          提高了代码的组织性可读性,更重要的是它使软件的可扩充性有了充分的提高;
l         是OOP的一个重要特征,提供了丰富的逻辑关系清晰的描述对象方法的手段,提高了软件功能和版本进化的设计维护能力。
 
C++支持两种多态性:
l          编译时多态:程序运行前发生的事件——函数重载、运算符重载——静态绑定
l          运行时多态:程序运行时发生的事件——虚函数机制          ——动态绑定
            
2.函数绑定(function call binding
绑定:将函数调用与函数体连接起来叫做绑定。
预绑定(early binding)绑定在程序运行之前进行(由编译器和连接器执行),也叫静态联编
后绑定(late binding)编译器在编译时未确定要调用的函数,必须根据程序运行所产生的信息来通知调用哪一个函数,也叫动态联编
C语言就只有一种绑定方式就是预绑定。
           
预绑定与后绑定的区别:
预绑定:
l          意味着绑定基于的信息都是静态的,是编译和连接时就可以确定的;
l         编译系统根据指针(或引用)本身的类型,而不是它所指向的对象的类型来进行绑定;
l         预绑定的实体包括一般函数、重载函数、非虚成员函数和非虚友元函数。
后绑定:
l          在运行时,根据对象类型的不同来选择合适的函数调用,这些类型信息在编译时是不可知的,故只能用后绑定解决这一问题;
l          拥有虚函数的类对象中,必然包含着相应的类型信息,否则动态绑定不可能实现;
l          编译时的多态的实现,取决于程序的静态信息是否足够为相同的程序实体确定不同的标识符。这里的程序实体,是指程序代码中的各种名称和代码段;
l         要实现运行时的多态,进行动态联编,就必须使用虚函数。
               
编译时的多态,表现在以下几方面:
l          对于在一个类中说明的重载,编译系统根据重载函数的参数个数、类型以及顺序的差别,来分别调用相应的函数;
l          对于在基类和派生类中重载函数,即使所带参数完全相同,由于它们属于不同的类,在编译时可以根据对象名前缀来加以区别;或者使用“类名::前缀,也可以指示编译器分辨出应该调用哪个类的成员函数;
l          调用编译时绑定的函数,优点是高效率,因为编译系统可以在运行前对代码进行优化;缺点是缺少灵活性,不能满足程序的可扩充性要求。
                     
                      

例1:编写基类、派生类、子派生类,在基类中定义虚函数,并全部实现,定义每个类的对象,观察每种对象的大小及其内存分配规律。

           
代码如下:
           
/************************************************************************
* 虚函数彻底研究
***********************************************************************
*/

#include 
<IOSTREAM.H>
//基类
class CBase
{
    
int x;
public:
    CBase(
int n) {x=n;}
    
~CBase(){}
    
virtual void SetX(int n) {x=n;}
    
virtual int GetX() {return x;}
}
;

//派生类
class CDerive : public CBase
{
    
int x;
public:
    CDerive(
int n1,int n2):CBase(n1)
    
{
        x
=n2;
    }

    
~CDerive() {}
    
void SetX(int n) {x=n;}
    
int GetX() {return x;}
}
;

//子派生类
class CSubDerive : public CDerive
{
    
int x;
public:
    CSubDerive(
int n1,int n2,int n3):CDerive(n1,n2)
    
{
        x
=n3;
    }

    
~CSubDerive() {}
    
void SetX(int n) {x=n;}
    
int GetX() {return x;}
}
;
void main()
{
    cout
<<"CBase size = "<<sizeof(CBase)<<endl;    
    cout
<<"CDerive size = "<<sizeof(CDerive)<<endl;
    cout
<<"CSubDerive size = "<<sizeof(CSubDerive)<<endl;

    CBase obj1(
1);    
    CDerive obj2(
2,3);    
    CSubDerive obj3(
4,5,6);

    CBase 
*pObj1=&obj1;    
    CDerive 
*pObj2=&obj2;    
    CSubDerive 
*pObj3=&obj3;

    CBase 
*pObj[]={pObj1,pObj2,pObj3};
}
               
1. 运行结果:
              
               
2. 对象的地址及内容:
           
           
             
       
           可以看出,子派生类的前4个字节(低地址)是虚函数表的地址,接下来的4个字节是从基类继承来的x,然后是由派生类继承来的x,最后才是该类的x(高地址);派生类的对象空间也如此。
           
3.  基类指针指向三个对象时,指针的内容:
             


要虚函数发挥作用,必须用基类的指针(或引用)指向派生类的对象,并用指针(或引用)调用虚函数。也就是说,只有用地址才能体现运行多态性。因为不论是指向基类还是指向派生类的指针(引用),大小都是一样的,这样才能用基类指针指向派生类对象。这时,指针提供的信息是不完全的,在编译阶段不知道应该调用虚函数的哪个版本。而如果用对象调用虚函数,由于类型已经确定了,因此编译系统很可能采用预绑定;

分享到:
评论

相关推荐

    C++多态与虚函数

    C++多态与虚函数,本章所讲的多态性指在继承类中与基类同名、同参数、同类型函数的不同行为。

    c++继承与多态,虚函数实例

    虚函数在实现多态中扮演着关键角色,它可以确保程序在运行时能够调用到正确的方法,即便对象的实际类型与指针或引用声明的类型不同。 首先,让我们深入理解“虚函数”这一概念。在C++中,虚函数通过在基类中使用`...

    实验七运行中的多态和虚函数

    ### 实验七:运行中的多态与虚函数 #### 实验背景 在面向对象编程中,多态是一种非常重要的概念,它允许我们使用一个接口来表示多种类型的行为。多态通常分为编译时多态(静态多态)和运行时多态(动态多态)。...

    C++实验六 多态性和虚函数的应用 课程 实验报告

    综上所述,该实验通过设计抽象类和派生类,使用虚函数实现多态性,展示了面向对象编程的关键概念,如继承、封装、多态和动态绑定。这些概念对于理解和编写复杂的C++程序至关重要。通过这样的实践,学生能够更好地...

    C++中的虚函数与多态

    在C++编程语言中,虚函数(Virtual Functions)和多态(Polymorphism)是面向对象编程的重要特性,它们使得程序具有高度的灵活性和可扩展性。本文将深入探讨这两个概念,结合示例代码进行详细解释。 首先,我们来...

    C++ 多态 虚函数 虚函数表 最是详细

    高质量的C++多态讲解,详细讲解虚函数,虚函数表,虚函数继承,虚函数继承下的内存分配等

    学习多态的虚函数例子

    学习多态的虚函数例子,更方便的理解多态,学习多态,更好的理解面向对象

    C++ 多态和虚函数 高清PDF

    多态性(在C + +中用虚函数实现)是面向对象程序设计语言继数据...虚函数反映了一个类型与另一个类似类型之间的区别,只要这两个类型都是从同一个基类派生的。这种区别是通过其在基类中调用的函数的表现不同来反映的。

    多态和虚函数[参照].pdf

    2. 静态成员函数不能是虚函数,因为它们不与特定对象关联。 3. 内联函数(`inline`)不能是虚函数,因为内联函数在编译时确定,而虚函数在运行时确定。 4. 构造函数不能是虚函数,但析构函数可以,并且通常应该声明...

    多态与虚函数计算面积

    一个小测试,可以认识到虚函数与多态性的认识

    c++多态和虚函数表

    ##### 2.1 继承与虚函数 继承是面向对象编程的一个基本特性,通过继承,子类可以继承父类的属性和方法。在C++中,如果希望一个类支持动态多态,则需要在这个类中声明至少一个虚函数。 示例代码: ```cpp // ...

    Part7-多态与虚函数-KEY.docx

    在C++编程语言中,多态性和虚函数是面向对象编程的重要特性,它们允许我们设计出灵活且可扩展的代码结构。多态性允许不同类型的对象以统一的方式进行处理,而虚函数是实现运行时多态性的关键机制。 1. **虚函数**:...

    Part7-多态与虚函数-KEY.pdf

    编译时多态主要通过函数重载(overload)实现,而运行时多态则通过虚函数(virtual function)和动态绑定实现。动态联编(dynamic binding)是运行时多态的一种表现形式,它在运行时根据对象的实际类型决定调用哪个...

    多态和虚函数[收集].pdf

    在设计良好的面向对象程序中,通常会采用这种多态的模式,让函数与基类接口交互,使得程序具备可扩展性。当添加新的子类时,只要它们遵循基类的接口,原有代码无需修改就能支持新类的行为。这种设计原则有助于创建...

    第12章 多态与虚函数.doc

    成员函数或指针-&gt;成员函数的方式调用非虚函数也是静态多态的例子,因为这些调用方式在编译时就可以确定具体执行哪个函数。 2. 动态多态性: 动态多态性主要通过虚函数(Virtual Functions)实现,它允许我们使用...

    实验8 多态:虚函数1

    实验8的主题是“多态:虚函数1”,主要目的是学习虚函数的应用以及通过异类数组实现多态调用。在C#编程语言中,虚函数是实现多态性的重要机制,允许子类重写父类的方法,使得父类指针可以调用子类的特定实现。 首先...

    c++多态性与虚函数练习题

    ### C++多态性与虚函数知识点解析 #### 一、多态性的概念 多态性是面向对象编程的一个核心特性,它允许我们通过基类的接口来操作派生类的对象。这种特性使得代码更加灵活且易于扩展。在C++中,多态性主要通过虚函数...

    c++,继承,多态,虚函数,纯虚函数

    ### C++ 中的继承、多态、虚函数与纯虚函数 #### 继承 **概念解析** 在面向对象编程语言如 C++ 中,继承是一种让一个类(派生类)能够继承另一个类(基类)特性的机制。这种机制不仅能够重用代码,还能在原有基础...

    C++面向对象技术完全剖析_源代码(继承,封装,多态,虚函数,纯虚函数,虚拟继承,多重继承,函数重载,指针……)

    要求:1、虚函数 多态 多态表现为 基类 基类指针和继承间的关系 2、带有多对象成员。定义 3、体现继承 虚拟继承(要通过至少三层 父类父类子类) 虚函数 (3层 纵向关系) 水平方向上:体现出继承顺序 先虚拟继承 ...

    C++多态虚函数表

    ### C++多态虚函数表详解 #### 一、多态的基本概念与内存分布 在C++中,多态是一种让程序可以根据不同的上下文表现出不同行为的重要机制。它允许我们使用基类类型的指针或者引用指向派生类的对象,从而在运行时...

Global site tag (gtag.js) - Google Analytics