1、静态联编和动态联编

1、联编是指一个程序模块、代码之间互相关联的过程。

2、静态联编(sta5c binding),是程序的匹配、连接在编译阶段实现,也称为早期匹配。重载函数使用静态联编。

3、动态联编是指程序联编推迟到运行时进行,所以又称为晚期联编(迟绑定)。switch 语句if 语句多态是动态联编的例子。

说明:

1、C++与C相同,是静态编译型语言

2、在编译时,编译器自动根据指针的类型判断指向的是一个什么样的对象;所以编译器认为父类指针指向的是父类对象。

3、由于程序没有运行,所以不可能知道父类指针指向的具体是父类对象还是子类对象,从程序安全的角度,编译器假设父类指针只指向父类对象,因此编 译的结果为调用父类的成员函数。这种特性就是静态联编。

4、多态的发生是动态联编,实在程序执行的时候判断具体父类指针应该调用的方法。

//A.动态联编的基础是虚函数
//B.动态联编时在运行时确定所调用的函数代码
//C.只有通过基类的指针或引用才能实现动态联编

2、虚析构函数

构造函数不能是虚函数。建立一个派生类对象时,必须从类层次的根开始,沿着继承路径逐个调用基类的构造函数。

析构函数可以是虚的虚析构函数用于指引 delete 运算符正确析构动态 对象

通常用于父类指针指向子类对象时,释放父类指针时会默认调用父类析构函数,而不会调用子类的析构函数,可能会造成内存泄漏。当把父类的析构函数定义为虚函数时,当释放父类指针时就会发生多态,先调用子类析构函数,再调用父类构造函数

3、重载、重写、重定义

重载(添加):

a 相同的范围(在同一个类中)

b 函数名字相同

c 参数不同 (个数或类型)

d virtual关键字可有可无

重写(覆盖) 是指派生类函数覆盖基类函数,特征是:

a 不同的范围,分别位于基类和派生类中

b 函数的名字相同

c 参数相同

d 基类函数必须有virtual关键字

重定义(隐藏) 是指派生类的函数屏蔽了与其同名的基类函数,规则如下:

a 如果派生类的函数和基类的函数同名,但是参数不同,此时,不管有无virtual,基类的函数被隐藏。

b 如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有vitual关键字,此时,基类的函数被隐藏。

即:重载:同一个作用域下(形参个数不同,类型不同)
       重写:如果父类是虚函数,子类在定义一遍。则为重写(虚函数重写)
       重定义:发生在两个不同的类中。一个是父类 一个是子类。 //父类普通函数,子类重新写了一遍(普通函数定义)
           即:1、普通函数重定义  如果父类的普通成员函数,被子类重写。说是重定义
                  2、虚函数重写 如果父类的虚函数,被子类重写,就是虚函数重写。这个函数会发生多态

虚析构函数代码示例:

#if 1
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#if 0
class A {
public:A() {cout << "A() " << endl;this->p = new char[64];//memset(this->p, 0, 64);strcpy(this->p, "A String...");}virtual void print() {cout << "A的print函数" << this->p << endl;}~A() {cout << "~A()" << endl;if (this->p != NULL) {delete this->p;this->p = NULL;}}
private:char *p;
};
class B :public A {
public:B() {  //会触发A的构造函数cout << "B() " << endl;this->p = new char[64];//memset(this->p, 0, 64);strcpy(this->p, "B String...");}virtual void print() {cout << "B的print函数" << this->p << endl;}~B() {cout << "~B()" << endl;if (this->p != NULL) {  //默认是B的pdelete this->p;this->p = NULL;}}
private:char* p;
};
void func(A *p) {p->print();
}
void test01() {A a; func(&a);cout << "------" << endl;B b;func(&b);
}
/*
A()
A的print函数A String...
------
A()
B()
B的print函数B String...
~B()
~A()
~A()
*/
void test02() {B *bp = new B;func(bp);delete bp;
}
/*
A()
B()
B的print函数B String...
~B()
~A()
*/
void func2(A *p) {p->print();  //发生多态delete p;    //也应该发生多态//此刻触发p默认的析构函数//应该是触发谁 调用谁的析构函数 多态
}
void test03() {A *ap = new A;func2(ap);
}
/*
A()
A的print函数A String...
*/
void test04() {B *bp = new B;func2(bp);
}
/*
A()
B()
B的print函数B String...
~A()
*/
#endif
//在上面的基础上,将A的析构函数改为虚函数
class A {
public:A() {cout << "A() " << endl;this->p = new char[64];//memset(this->p, 0, 64);strcpy(this->p, "A String...");}virtual void print() {cout << "A的print函数" << this->p << endl;}virtual ~A() {cout << "~A()" << endl;if (this->p != NULL) {delete this->p;this->p = NULL;}}
private:char *p;
};
class B :public A {
public:B() {  //会触发A的构造函数cout << "B() " << endl;this->p = new char[64];//memset(this->p, 0, 64);strcpy(this->p, "B String...");}virtual void print() {cout << "B的print函数" << this->p << endl;}virtual ~B() {cout << "~B()" << endl;if (this->p != NULL) {  //默认是B的pdelete this->p;this->p = NULL;}}
private:char* p;
};
void func2(A *p) {p->print();delete p;    //此刻触发p默认的析构函数//应该是触发谁 调用谁的析构函数 多态
}
void test05() {B *bp = new B;func2(bp);
}
/*
A()
B()
B的print函数B String...
~B()
~A()
*/
int main() {//test01();//test02();//test03();//test04();test05();return 0;
}//重载:同一个作用域下(形参个数不同,类型不同)
//重写:如果父类是虚函数,子类在定义一遍。则为重写(虚函数重写)
//重定义:发生在两个不同的类中。一个是父类 一个是子类。//父类普通函数,子类重新写了一遍(普通函数定义)
//即:1、普通函数重定义  如果父类的普通成员函数,被子类重写。说是重定义
//    2、虚函数重写 如果父类的虚函数,被子类重写,就是虚函数重写。这个函数会发生多态//A.动态联编的基础是虚函数
//B.动态联编时在运行时确定所调用的函数代码
//C.只有通过基类的指针或引用才能实现动态联编
#endif

C++基础16-类和对象之联编,重写,虚析构相关推荐

  1. JAVA基础七 类和对象

    文章目录 JAVA基础七 类和对象 01 引用 02 继承 03 方法重载 04 构造方法 05 this 06 传参 07 包 08 访问修饰符 09 类属性 10 类方法 11 属性初始化 12 ...

  2. JAVA基础––从类和对象开始

    JAVA基础--从类和对象开始 一.概念 1.面向对象中类和对象的概念 对象:对象是具有状态和行为的实体,例如某个具体的学生,或者是王者荣耀里的英雄,可以是物理实体,也可以是逻辑实体. 类:类是一组具 ...

  3. Java_面向对象基础(类、对象、方法和构造函数)

    Java的面向对象基础(类.对象.方法和构造函数) 面向对象的基本概念 面向对象的设计思想 什么是类 什么是对象 类的定义 设计面向对象的例子 步骤一:设计动物这个类 步骤二:创建具体的动物 步骤三: ...

  4. 【C++基础】类和对象——友元

    [C++基础]类和对象--友元 友元的概念 在C++中,不能被外部访问的私有属性,通过友元可以访问. 友元的关键字:friend 友元的三种实现 全局函数做友元 类做友元 成员函数做友元 一.全局函数 ...

  5. java基础(类与对象、集合)

    java基础(类与对象.集合) 类与对象 类与对象中的栈和堆 构造方法 this关键字 面向对象三大特性 封装性(private) 继承性(extends) 方法重写(@override) 多态性 向 ...

  6. 虚拟函数-1、静态联编与动态联编,引入虚函数

    在实际开发工作中,为提高代码的重用性,编写通用的功能模块,往往需要设计处理几种不同对象的通用程序,如示例2.1所示. 示例清单2.1 #include "stdio.h" #inc ...

  7. 刻意练习:Python基础 -- Task10. 类与对象

    背景 我们准备利用17天时间,将 "Python基础的刻意练习" 分为如下任务: Task01:变量.运算符与数据类型(1day) Task02:条件与循环(1day) Task0 ...

  8. 基础01类与对象、封装、构造方法

    面向对象思想: 面向过程:当需要实现一个功能的时候,每一个具体的步骤都要亲力亲为,详细处理每一个细节. 面向对象:当需要实现一个功能的时候,不关心具体的步骤,而是找一个已经具有该功能的人,来帮我做事儿 ...

  9. JAVA面向对象编程学习 (1)语法基础与类与对象

    读入函数 Scanner in=new Scanner(System.in);System.out.println(in.nextLine()); 意思是先new一个Scanner类的对象叫in,然后 ...

最新文章

  1. luogu P4108 [HEOI2015]公约数数列(分块、gcd性质)
  2. 删除条目时的确认对话框
  3. [html] 页面布局时你使用最多的标签是什么?div吗?在什么情况下会使用到div?
  4. 矩阵加法(信息学奥赛一本通-T1124)
  5. 气愤ing,身份证丢了到底要不要挂失?
  6. airflow 部署
  7. java检查变量是否定义_JavaScript检查变量是否存在(已定义/初始化)
  8. Python2 和 pip2 存在, Python3 也存在,但是 pip3 不存在的解决办法
  9. 偏标记(partial)学习
  10. 南阳理工学院计算机acm,南阳理工学院计算机学院ACM队成员获奖情况[荣誉记]
  11. 红米AC2100刷固件心得
  12. 计算机网络中netbuie,材料内部空隙体积占其总体积的百分率叫做()。A、孔隙率B、填充率C、空隙率D、密实度...
  13. 永磁同步电机的矢量控制策略(十二)一一一MTPA最大转矩电流比控制
  14. X509 证书 检验是否过期,私钥签名,公钥验签
  15. 计算机标题怎么操作,电脑的ppt 一级,二级,三级标题怎么设置
  16. java测试用例生成器_软件测试之用TestDirector生成测试用例完整版.doc
  17. 英语邮件中常用的礼貌用语
  18. 百度×TCL丨鸿鹄语音芯片首次在家电行业量产!
  19. 一款 Material Design 风格的妹子福利 App.
  20. 学计算机得肩周炎,电脑工作者更易患肩周炎 肩周炎的自我按摩方法

热门文章

  1. Mysql中几种插入效率的实例对比
  2. Java基础篇2——运算符
  3. 向量除法能用计算机吗,为什么向量没有除法
  4. android 开源图表动画,Android 图表开发开源库MPAndroidChart-Go语言中文社区
  5. cls certificate.php,php加密解密处理类
  6. C语言6F多少,求助!!请人帮忙画C语言程序流程图.紧急!!!
  7. python 手机编程termux_如何优雅的在手机上进行Python编程?
  8. 排序算法 —— 计数排序
  9. 数据结构与算法————稀疏数组
  10. 鸿蒙系统定位低端市场,明年年初见!鸿蒙系统会先定位中低端,后续全面升级...