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

1、静态联编和动态联编

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

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

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

说明:

1C++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

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/567858.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c语言环境变量的作用,C语言获取系统环境变量

C语言获取系统环境变量可以通过如下代码实现.#include #include char *platform(){//获取系统变量信息char *ret;extern char **environ;char **env environ;//打印系统变量信息/*while(*env){//puts(*env);env;}*/ret getenv("OS"); //for windows_ntif(NULL ! re…

C++基础17-纯虚函数和抽象类

总结&#xff1a; 1,含有纯虚函数的类,称为抽象基类,不可实列化。即不能创建对象,存在 的意义就是被继承,提供族类的公共接口。 2,纯虚函数只有声明,没有实现,被“初始化”为 0。 3,如果一个类中声明了纯虚函数,而在派生类中没有对该函数定义,则该虚函数在派生类中仍然为纯…

c语言wpf99乘法表,使用JSP输出九九乘法表

R数据实战vehicles--1新建项目vehicles-project 数据文件vehicles.csv与varlabels.txt放在项目文件中【CSS3】---颜色RGBA及渐变色颜色之RGBA RGB是一种色彩标准,是由红(R).绿(G).蓝(B)的变化以及相互叠加来得到各式各样的颜色.RGBA是在RGB的基础上增加了控制alpha透明度的参数…

C++基础18-抽象类-电脑组装练习

01电脑组装me.cpp 需要实现所有的虚函数&#xff0c;不台灵活。架构函数无法写&#xff0c;设计不够成熟 #if 1 #include<iostream> using namespace std; class Computer { public:virtual void caculate() 0;virtual void display() 0;virtual void storage() 0; …

以串结构存储c语言版,数据结构C语言版 串的块链存储表示和实现

《数据结构C语言版 串的块链存储表示和实现》由会员分享&#xff0c;可在线阅读&#xff0c;更多相关《数据结构C语言版 串的块链存储表示和实现(13页珍藏版)》请在人人文库网上搜索。1、*数据结构C语言版 串的块链存储表示和实现P78编译环境&#xff1a;Dev-C 4.9.9.2日期&…

mysql索引创建及使用注意事项

总结&#xff1a; 1、在使用索引时&#xff0c;一般情况下不建议使用like操作。如果使用&#xff0c;则%放在后面。否则不会使用索引。like ‘%abd%’不会使用索引,而like ‘aaa%’可以使用索引.&#xff08;最左缀原则&#xff09; 2、单列索引的使用&#xff1a; 《1》 只…

mulitpartfile怎么接收不到值_和平精英信号接收区和信号值是什么?信号值怎么恢复...

[闽南网]和平精英公测开启&#xff0c;和平精英与刺激战场有什么不同呢&#xff1f;今天小编就为大家带来了信号值详解&#xff01;各位玩家千万不要错过呀&#xff01;信号值详解信号接收区和信号值是什么&#xff0c;对选手有什么影响&#xff1f;在游戏战斗界面中&#xff0…

c语言编程判断素数的函数,【面试题】C语言:实现一个函数,判断一个数是不是素数。...

#include#include#includeint prime(int num){int k 0;int i 0;k sqrt(num);for (i 2; i < k; i) /*不满足循环条件时即均不可被整除&#xff0c;不是素数*/{if (num%i 0){return 0;}}return -1;}int main(){int num 0;int ret 0;printf("please input the nu…

Linux命令 umask,chmod使用

一、文件权限详解 1、文件权限介绍 在linux中的每一个文件或目录都包含有访问权限&#xff0c;这些访问权限决定了谁能访问和如何访问这些文件和目录。通过设定权限可以从以下三种访问方式限制访问权限&#xff1a;只允许用户自己访问&#xff1b;允许一个预先指定的用户组中…

python启动c语言gdb,使用gdb调试python程序

游戏服务器菜鸟之C&num;初探三游戏服务在经过上述2番折腾之后,最后决定使用TCP进行通信,所以在一次进行重构 主要重构的要点 1.将过来的HTPP请求,重构为TCP请求: 2.使用组件FluenScheduler进行怪物的定时刷新,和定时 ...Windows环境下的NodeJS&plus;NPM&plus;Bower…

制备pdms膜的方法_船体用钢板基底超疏水表面的制备和性能

鲨鱼皮具有神奇的微纳双层结构&#xff0c;其微米级肋条状结构在水中的整流效果可减小水的阻力。纳米级刺状突起或刚毛具有疏水特性&#xff0c;使植物抱子很难附着其上&#xff0c;海藻等植物也不能在其表面生长&#xff3b;1,2&#xff3d;。这种微纳结构及其疏水性的共同作用…

递归题型解析

#include<iostream> using namespace std; int foo(int n) {if (n < 1)return n;return (foo(n - 1) foo(n - 2)); } int main() {printf("%d\n", foo(5));return 0; } 解析&#xff1a; foo(5)foo(4)f00(3)foo(3)foo(2)foo(3)2foo(3)foo(2)2(foo(2)foo(1…

64位c语言调用32位glibc,glibc fclose源代码阅读及伪造_IO_FILE利用fclose实现任意地址执行...

简介最近学习了一下_IO_FILE的利用&#xff0c;刚好在pwnable.tw上碰到一道相关的题目。拿来做了一下&#xff0c;遇到了一些困难&#xff0c;不过顺利解决了&#xff0c;顺便读了一波相关源码&#xff0c;对_IO_FILE有了更深的理解。文章分为三部分&#xff0c;分别是利用原理…

戴尔笔记本电脑开机黑屏怎么办_戴尔笔记本电脑充不进电怎么办

笔记本电脑电池充不进电要怎么办呢&#xff1f;笔记本电脑之所以这么受欢迎&#xff0c;是因为笔记本有配备电池&#xff0c;能够在没有电源的情况下使用五六个小时。而电池的电用光后&#xff0c;就需要进行充电。不过有些用户反映说&#xff0c;自己的电池充不进电&#xff0…

linux之trap命令

一. trap捕捉到信号之后&#xff0c;可以有三种反应方式&#xff1a;   (1)执行一段程序来处理这一信号   (2)接受信号的默认操作   (3)忽视这一信号 二. trap对上面三种方式提供了三种基本形式&#xff1a; 第一种形式的trap命令在shell接收到signal list清单中数…

IIS安装2个SSL_顶级域名0元撸-免费注册2个腾讯云域名 免费SSL证书

前言这两天折腾甜糖CDN&#xff0c;为了收益最大化申请了公网IP&#xff0c;于是顺带折腾了一下群晖外网访问。使用的DDNS方案是腾讯dnspod&#xff0c;注册一个便宜的顶级域名访问我的群晖&#xff0c;折腾过程中发现可以免费注册2个顶级域名&#xff0c;不敢独享发出来大家一…

c语言中文刷屏,c语言二维数组刷屏练习.doc

c语言二维数组刷屏练习// 二维数组的刷屏综合练习 编制于2012.9.23#include#include#include#include#define WIDTH 22//宏定义/***********************函数声明**********************************************/void init();//数组赋初值void print();//显示当前数组void mov…

三菱a系列motion软体_工控电缆如何制作?(以三菱PLC、触摸屏为例)

RS232接口的三菱Q系列PLC编程通讯电缆三菱GT11/GT15触摸屏RS232串口编程电缆三菱GT11/GT15触摸屏连接Q系列PLC电缆三菱GT11/GT15触摸屏连接FX2/FX2C/A/QnA系列PLC电缆三菱GT11/GT15 触摸屏连接FX3U/FX2N/FX1N系列PLC电缆FX2、A系列PLC到A970GOT人机介面连接电缆FX0s/FX0n/FX2n/…

c语言水仙花验证,[编程入门]水仙花数判断 (C语言代码)

解题思路:三个变量 判断一下 yes就输出注意事项:参考代码:#include using namespace std;int a[5];int used[5];int print[4];void dfs(int cur,int cont){if(cur 4){for(int i 1;i < 3;i){cout<}cout<return;}for(int i 1;i < 4;i){if(used[i] 0&&i !…

C/C++混淆点-与

简介&#xff1a; &&是逻辑与运算符&#xff0c;||是逻辑或运算符&#xff0c;都是逻辑运算符&#xff0c;两边只能是bool类型 &与| 既可以进行逻辑运算&#xff0c;又可以进行位运算&#xff0c;两边既可以是bool类型&#xff0c;又可以是数值类型 区别&#xf…