码迷,mamicode.com
首页 > 编程语言 > 详细

C++的静态联编和动态联编

时间:2020-04-22 23:02:09      阅读:237      评论:0      收藏:0      [点我收藏+]

标签:ext   处理   style   模块   sdn   就会   参考   http   csdn   

一、概述:

联编就是将 模块或者函数 合并在一起生成可执行代码的处理过程(也可以叫做绑定),同时对每个模块或者函数调用分配内存地址,并且对外部访问也分配正确的内存地址,它是计算机程序彼此关联的过程。按照联编所进行的阶段不同,可分为两种不同的联编方法:静态联编动态联编

1.静态联编

是指在编译阶段就将函数实现和函数调用关联起来,因此静态联编也叫早绑定,在编译阶段就必须了解所有的函数或模块执行所需要检测的信息,它对函数的选择是基于指向对象的指针(或者引用)的类型,C语言中,所有的联编都是静态联编,并且任何一种编译器都支持静态联编。

动态联编

指在程序执行的时候才将函数实现和函数调用关联,因此也叫运行时绑定或者晚绑定动态联编对函数的选择不是基于指针或者引用,而是基于对象类型不同的对象类型将做出不同的编译结果C++中一般情况下联编也是静态联编,但是一旦涉及到多态和虚函数就必须要使用动态联编了。虚函数是实现动态联编的基础

多态

字面的含义是具有多种形式、形态。C++多态有两种形式,动态多态静态多态;动态多态是指一般的多态,动态多态是通过类继承和虚函数机制实现的多态;静态多态是通过模板来实现,因为这种多态实在编译时而非运行时,所以称为静态多态。

模板函数

参考https://blog.csdn.net/mr_h9527/article/details/82598237

 

二、实例

动态多态--通过类的继承和虚函数实现

#include <stdio.h>
#include <iostream>
class CShape//图形类、基类
{
public:
    CShape(){}
    virtual ~CShape(){}//析构函数也声明为虚函数,为了析构彻底!
    virtual void Draw() = 0;//把想要多态的函数声明为虚函数
};

class CPoint : public CShape//点类
{
public:
    CPoint(){}
    ~CPoint(){}
    void Draw()
    {printf("Hello! I am Point!\n");}
};

class CLine : public CShape //线类
{
public:
    CLine(){}
    ~CLine(){}
    void Draw()
    {printf("Hello! I am Line!");}
};


int main()
{
    CShape* shape = new CPoint();//手动分配内存,new 生成了一个点类对象,基类指针可以指向派生类的对象(多态性)!!!
    
    //draw point
    shape->Draw();//shape将会调用CPoint的Draw()函数,而不是基类的Draw方法
    delete shape;
    //并不是删除指针,而是删除指针指向的对象,因为基类的析构函数被声明为虚函数,因此会调用该指针指向的派生类的析构函数,
    //而派生类的析构函数又会自动调用基类的析构函数,这样整个派生类的对象会被完全释放

    shape = new CLine();
    //draw Line
    shape->Draw();//shape将会调用CLIne 的Draw()函数
    delete shape;

    return 0;
}

 

一个Draw() 可以有两种实现,并且是在运行时决定的,在编译阶段不知道,只有在运行的时候才能知道我们生成的shape是那种图形,

当然要实现这种效果就需要动态联编了,在基类我们会把想要多态的函数声明为虚函数(前面加上 virtual关键字),而虚函数的实现原理就使用了动态联编。

 

静态多态----通过模板实现

在上面例子的基础之上添加模板函数

template <class T>
void DrawShape(T*   t)
{
   t->Draw();
}

main函数修改为

void main()
{
 CShape* shape = new CPoint();
//draw point shape->Draw(); DrawShape<CPoint>((CPoint*)shape); //模板函数的调用方法:模板名<用来实例化模板的类型>(参数)delete shape;
shape
= new CLine(); //draw Line shape->Draw(); DrawShape<CLine>((CLine*)shape); delete shape; return ; }

 在程序编译main函数的时候,编译器就已经指定了DrawShape函数里面的Draw要调用那个实现了,这就是静态多态,在编译时就已经知道了要调用的函数。

 

 

三、虚函数的使用

基类析构函数为虚函数

(1)基类析构函数定义为虚函数时:基类指针可以指向派生类的对象(多态性),如果删除该基类指针delete [  ]p(并不是删除指针,而是删除指针所指向的对象);就会调用该指针指向的派生类析构函数,而派生类的析构函数又自动调用基类的析构函数,这样整个派生类的对象完全被释放

(2)基类析构函数不定义为虚函数时:编译器实施静态绑定,在删除基类指针时,只会调用基类的析构函数而不调用派生类析构函数,这样就会造成派生类对象析构不完全

C++的静态联编和动态联编

标签:ext   处理   style   模块   sdn   就会   参考   http   csdn   

原文地址:https://www.cnblogs.com/hemengjita/p/12756225.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!