C++基础之继承续(十六)

一.基类与派生类之间的转换

  1. 可以把派生类赋值给基类
  2. 可以把基类引用绑定派生类对象
  3. 可以把基类指针指向派生类对象
#include <iostream>using std::cin;
using std::cout;
using std::endl;//基类与派生类相互转化
class Base
{
private:int _x;
public:Base(int x=0):_x(x){cout<<"Base()"<<endl;}~Base(){cout<<"~Base()"<<endl;}void show(){cout<<"_x ="<<_x<<endl;}
};class Derived:public Base
{private:int _y;public:Derived(int x=0,int y=0):Base(x),_y(y){cout<<"Derived()"<<endl;}~Derived(){cout<<"~Derived()"<<endl;}void show(){cout<<"_y ="<<_y<<endl;}
};void test()
{Base base(3);Derived derived(5,4);derived.show();base.show();cout<<"派生类向基类转换"<<endl;base=derived;base.show();derived.show();Base& base1=derived;Base* base2=&derived;base1.show(); base2->show();Base base3=derived;}int main()
{test();return 0;}

当派生类转换为基类时,派生类将初始完基类的数据成员再赋给基类。如果需要将基类转换为派生类需要加强制类型转换。

二.派生类间的复制控制

        如果基类实现了拷贝构造函数或赋值运算符函数,但是派生类没有实现拷贝构造函数或赋值运算符函数,那么在将一个已经存在的派生类对象初始化一个刚刚创建的派生类对象会调用拷贝构造函数,或者进行两个对象进行赋值时调用赋值运算符函数,由于派生类没有拷贝构造函数那么派生部分就会执行缺省行为,而基类部分会调用基类的构造函数和赋值运算符函数。

1.当派生类无新数据成员时

#include <iostream>
#include <string.h>
using std::cout;
using std::endl;class Base
{
private:char* _pbase;
public:Base(const char* str):_pbase(new char[strlen(str)+1]()){cout<<"Base(const char* str)"<<endl;strcpy(_pbase,str);}~Base(){cout<<"~Base()"<<endl;if(_pbase!=nullptr){delete[]_pbase;_pbase=nullptr;}}Base():_pbase(nullptr){cout<<"Base()"<<endl;}Base(const Base& rhs):_pbase(new char[strlen(rhs._pbase)+1]()){cout<<"Base(const Base& rhs)"<<endl;strcpy(_pbase,rhs._pbase);}Base& operator=(const Base& rhs){//自复制if(this != &rhs){cout<<"Base& operator=(const Base& rhs)"<<endl;if(_pbase!=nullptr){delete[] _pbase;_pbase=nullptr;}_pbase=new char[strlen(rhs._pbase)+1]();strcpy(_pbase,rhs._pbase);}return *this;}friend std::ostream& operator<<(std::ostream& os,const Base& rhs);};class Derived
: public Base
{public:Derived(const char* str1):Base(str1){cout<<"Derived(const char* str1)"<<endl;}~Derived(){cout<<"~Derived()"<<endl;}friend std::ostream& operator<<(std::ostream& os,const Derived& rhs);
};std::ostream& operator<<(std::ostream& os,const Derived& rhs)
{const Base &base=rhs;os<<base;return os;
}
std::ostream& operator<<(std::ostream& os,const Base& rhs)
{if(rhs._pbase){os<<rhs._pbase;}return os;
}void test()
{Derived derived("hello");cout<<"derived = "<<derived<<endl;cout<<endl;Derived derived1(derived);cout<<"derived = "<<derived<<endl;cout<<"derived1 = "<<derived1<<endl;cout<<endl;Derived derived2("你好");cout<<"derived2 = "<<derived2<<endl;cout<<endl;derived2=derived;cout<<"derived = "<<derived<<endl;cout<<"derived2 = "<<derived2<<endl;
}int main()
{test();return 0;
}

2.当派生类有新数据成员时

#include <iostream>
#include <string.h>
using std::cout;
using std::endl;class Base
{
private:char* _pbase;
public:Base(const char* str):_pbase(new char[strlen(str)+1]()){cout<<"Base(const char* str)"<<endl;strcpy(_pbase,str);}~Base(){cout<<"~Base()"<<endl;if(_pbase!=nullptr){delete[]_pbase;_pbase=nullptr;}}Base():_pbase(nullptr){cout<<"Base()"<<endl;}Base(const Base& rhs):_pbase(new char[strlen(rhs._pbase)+1]()){cout<<"Base(const Base& rhs)"<<endl;strcpy(_pbase,rhs._pbase);}Base& operator=(const Base& rhs){//自复制if(this != &rhs){cout<<"Base& operator=(const Base& rhs)"<<endl;if(_pbase!=nullptr){delete[] _pbase;_pbase=nullptr;}_pbase=new char[strlen(rhs._pbase)+1]();strcpy(_pbase,rhs._pbase);}return *this;}friend std::ostream& operator<<(std::ostream& os,const Base& rhs);
};class Derived
: public Base
{
private:char* _pderived;
public:Derived(const char* str1,const char* str2):Base(str1),_pderived(new char[strlen(str2)+1]()){cout<<"Derived(const char* str1,const char* str2)"<<endl;strcpy(_pderived,str2);}Derived(const Derived& rhs):_pderived(new char[strlen(rhs._pderived)+1]()){cout<<"Derived(const Derived& rhs)"<<endl;strcpy(_pderived,rhs._pderived);}Derived& operator=(const Derived& rhs){cout<<"Derived& operator=(const Derived& rhs)"<<endl;if(this != &rhs){if(_pderived!=nullptr){delete[]_pderived;_pderived=nullptr;}_pderived=new char[strlen(rhs._pderived)+1]();strcpy(_pderived,rhs._pderived);}return *this;}~Derived(){cout<<"~Derived()"<<endl;if(_pderived!=nullptr){delete[]_pderived;_pderived=nullptr;}}friend std::ostream& operator<<(std::ostream& os,const Derived& rhs);   
};std::ostream& operator<<(std::ostream& os,const Derived& rhs)
{const Base &base=rhs;os<<base<<" , "<<rhs._pderived;return os;
}
std::ostream& operator<<(std::ostream& os,const Base& rhs)
{if(rhs._pbase){os<<rhs._pbase;}return os;
}
void test()
{Derived derived("hello","world");cout<<"derived = "<<derived<<endl;cout<<endl;Derived derived1(derived);cout<<"derived = "<<derived<<endl;cout<<"derived1 = "<<derived1<<endl;cout<<endl;Derived derived2("你好","世界");cout<<"derived2 = "<<derived2<<endl;cout<<endl;derived2=derived;cout<<"derived = "<<derived<<endl;cout<<"derived2 = "<<derived2<<endl;
}int main()
{test();return 0;
}

        如果基类和派生类都实现了拷贝构造函数和赋值运算符函数,那么在将一个已经存在的派生类对象初始化一个刚刚创建的派生类对象,或者两个派生类对象进行赋值时,派生类数据成员部分会执行派生类自己的拷贝构造函数或赋值运算符函数,而基类部分不会执行基类的拷贝构造函数或赋值运算符函数,除非在派生类中显示的调用基类的拷贝与赋值。

3.改进

#include <iostream>
#include <string.h>
using std::cout;
using std::cin;
using std::endl;class Base
{
private:char* _pbase;
public:Base(const char* str):_pbase(new char[strlen(str)+1]()){cout<<"Base(const char* str)"<<endl;strcpy(_pbase,str);}~Base(){cout<<"~Base()"<<endl;if(_pbase!=nullptr){delete[]_pbase;_pbase=nullptr;}}Base():_pbase(nullptr){cout<<"Base()"<<endl;}Base(const Base& rhs):_pbase(new char[strlen(rhs._pbase)+1]()){cout<<"Base(const Base& rhs)"<<endl;strcpy(_pbase,rhs._pbase);}Base& operator=(const Base& rhs){//自复制if(this != &rhs){cout<<"Base& operator=(const Base& rhs)"<<endl;if(_pbase!=nullptr){delete[] _pbase;_pbase=nullptr;}_pbase=new char[strlen(rhs._pbase)+1]();strcpy(_pbase,rhs._pbase);}return *this;}friend std::ostream& operator<<(std::ostream& os,const Base& rhs);};class Derived
: public Base
{
private:char* _pderived;
public:Derived(const char* str1,const char* str2):Base(str1),_pderived(new char[strlen(str2)+1]()){cout<<"Derived(const char* str1,const char* str2)"<<endl;strcpy(_pderived,str2);}Derived(const Derived& rhs):Base(rhs)    //显示调用拷贝构造函数,_pderived(new char[strlen(rhs._pderived)+1]()){cout<<"Derived(const Derived& rhs)"<<endl;strcpy(_pderived,rhs._pderived);}Derived& operator=(const Derived& rhs){cout<<"Derived& operator=(const Derived& rhs)"<<endl;Base::operator=(rhs);//显示调用赋值运算符函数if(this != &rhs){if(_pderived!=nullptr){delete[]_pderived;_pderived=nullptr;}_pderived=new char[strlen(rhs._pderived)+1]();strcpy(_pderived,rhs._pderived);}return *this;}~Derived(){cout<<"~Derived()"<<endl;if(_pderived!=nullptr){delete[]_pderived;_pderived=nullptr;}}friend std::ostream& operator<<(std::ostream& os,const Derived& rhs);};std::ostream& operator<<(std::ostream& os,const Derived& rhs)
{const Base &base=rhs;os<<base<<" , "<<rhs._pderived;return os;
}
std::ostream& operator<<(std::ostream& os,const Base& rhs)
{if(rhs._pbase){os<<rhs._pbase;}return os;
}void test()
{Derived derived("hello","world");cout<<"derived = "<<derived<<endl;cout<<endl;Derived derived1(derived);cout<<"derived = "<<derived<<endl;cout<<"derived1 = "<<derived1<<endl;cout<<endl;Derived derived2("你好","世界");cout<<"derived2 = "<<derived2<<endl;cout<<endl;derived2=derived;cout<<"derived = "<<derived<<endl;cout<<"derived2 = "<<derived2<<endl;}int main()
{test();return 0;
}

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

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

相关文章

Amuse .NET application for stable diffusion

Amuse github地址&#xff1a;https://github.com/tianleiwu/Amuse .NET application for stable diffusion, Leveraging OnnxStack, Amuse seamlessly integrates many StableDiffusion capabilities all within the .NET eco-system Welcome to Amuse! Amuse is a profes…

CAPL - 如何实现弹窗提示和弹窗操作(续)

目录 函数介绍 openPanel closePanel 代码示例 1、简单的打开关闭panel面板

自动驾驶-如何进行多传感器的融合

自动驾驶-如何进行多传感器的融合 附赠自动驾驶学习资料和量产经验&#xff1a;链接 引言 自动驾驶中主要使用的感知传感器是摄像头和激光雷达&#xff0c;这两种模态的数据都可以进行目标检测和语义分割并用于自动驾驶中&#xff0c;但是如果只使用单一的传感器进行上述工作…

文献速递:文献速递:基于SAM的医学图像分割--SAM-Med3D

Title 题目 SAM-Med3D 01 文献速递介绍 医学图像分析已成为现代医疗保健不可或缺的基石&#xff0c;辅助诊断、治疗计划和进一步的医学研究]。在这一领域中最重要的挑战之一是精确分割体积医学图像。尽管众多方法在一系列目标上展现了值得称赞的有效性&#xff0c;但现有的…

C/C++ 语言中的 ​if...else if...else 语句

C/C 语言中的 ​if...else if...else 语句 1. if statement2. if...else statement3. if...else if...else statementReferences 1. if statement The syntax of the if statement is: if (condition) {// body of if statement }The code inside { } is the body of the if …

javaScript——BFS结合队列求迷宫最短路径

这里推荐先去看下B站这个老师讲的BFS迷宫问题&#xff0c;只用看前五分钟就能懂用BFS队列实现的原理。[POJ] 3984 迷宫问题 BFS_哔哩哔哩_bilibili 问题描述&#xff1a;由m*n的矩阵构成了一个迷宫&#xff0c; 矩阵中为1的元素表示障碍物&#xff0c;不能走&#xff0c;为0表示…

AcWing 830. 单调栈

解题思路 对于将要入栈的元素来说&#xff0c;在对栈进行更新后&#xff08;即弹出了所有比自己大的元素&#xff09;&#xff0c;此时栈顶元素就是数组中左侧第一个比自己小的元素&#xff1b; 对于将要入栈的元素来说&#xff0c;在对栈进行更新后&#xff08;即弹出了所有比…

【干货】无源滤波器设计讲解,工作原理+设计步骤

今天给大家分享的是&#xff1a;无源模拟滤波器针对很多入门小白不懂滤波器设计&#xff0c;一些老工程师上班很多年有的也不懂得总结知识点&#xff0c;以及想学习不知道怎么系统学习的这一类人群&#xff0c;前方知识点来袭&#xff0c;请君放心食用~ 在信号处理领域&#x…

Git基础(25):Cherry Pick合并指定commit id的提交

文章目录 前言指定commit id合并使用TortoiseGit执行cherry-pick命令 前言 开发中&#xff0c;我们会存在多个分支开发的情况&#xff0c;比如dev&#xff0c;test, prod分支&#xff0c;dev分支在开发新功能&#xff0c;prod作为生产分支已发布。如果某个时候&#xff0c;我们…

基于stm32与TJC3224T124_011串口屏的PID调参器(附完整工程)

电赛在即&#xff0c;每次比赛调PID都是一件比较繁琐的事。每次都要在程序中改完再烧录到板子上&#xff0c;特别耗时。正好最近发现实验室的一块串口屏比较好玩。 于是就做了这个调PID的东西。它可以通过串口直接修改PID的值&#xff0c;从而达到快速调PID的目的。下面我将完整…

论文阅读---VITC----Early Convolutions Help Transformers See Better

论文题目&#xff1a;Early Convolutions Help Transformers See Better 早期的卷积网络帮助transformers性能提升 vit 存在不合格的可优化性&#xff0c;它们对优化器的选择很敏感。相反现代卷积神经网络更容易优化。 vit对优化器的选择[40](AdamW [27] vs. SGD)&#xff0…

CTF题型 nodejs(1) 命令执行绕过典型例题

CTF题型 nodejs(1) 命令执行绕过 文章目录 CTF题型 nodejs(1) 命令执行绕过一.nodejs中的命令执行二.nodejs中的命令绕过1.编码绕过2.拼接绕过3.模板字符串4.Obejct.keys5.反射6.过滤中括号的情况典型例题1.[GFCTF 2021]ez_calc2.[西湖论剑 2022]Node Magical Login 一.nodejs中…

力扣Lc21--- 389. 找不同(java版)-2024年3月26日

1.题目描述 2.知识点 &#xff08;1&#xff09;在这段代码中&#xff1a; // 统计字符串s中每个字符的出现次数for (int i 0; i < s.length(); i) {count[s.charAt(i) - a];}对于字符串s “abcd”&#xff1a; 当 i 0&#xff0c;s.charAt(i) ‘a’&#xff0c;ASCII…

yolov9目标检测可视化图形界面GUI源码

该系统是由微智启软件工作室基于yolov9pyside6开发的目标检测可视化界面系统 运行环境&#xff1a; window python3.8 安装依赖后&#xff0c;运行源码目录下的wzq.py启动 程序提供了ui源文件&#xff0c;可以拖动到Qt编辑器修改样式&#xff0c;然后通过pyside6把ui转成python…

JMeter 如何并发执行 Python 脚本

要在JMeter中并发执行Python脚本&#xff0c;可以使用Jython脚本或通过调用外部Python脚本的方式实现。 使用Jython脚本并发执行Python脚本的步骤&#xff1a; 1、创建一个线程组&#xff1a;在JMeter界面中&#xff0c;右键点击测试计划&#xff0c;选择 “添加” -> “线…

词根词缀基础

一&#xff0e;词根词缀方法&#xff1a; 1. 类似中文的偏旁部首&#xff08;比如“休”单人旁木→一个人靠木头上休息&#xff09; 2. 把单词拆分后&#xff0c;每一个部分都有它自己的意思&#xff0c;拼凑在一起就构成了这个单词的意思 3. 一个规律&#xff0c;适用大部分…

题。。。。

O - 胜利大逃亡(续) 题目分析 bfs状态压缩&#xff08;在bfs的基础上&#xff0c;存储持有不同钥匙时&#xff0c;此点位是否走过的情况&#xff09;&#xff1b; -----状态压缩使用二进制实现&#xff0c;同时通过位运算修改是否转移至另一状态&#xff08;详情见代码及注释…

javaWeb校园二手平台项目

一、系统分析 1.1开发背景 随着全世界互联网技术的不断发展&#xff0c;各种基于互联网技术的网络应用不断涌现,网络技术正在不断的深入人们的生活。人们从Internet上获取信息、享受生活、交流感情、网上工作等。Internet正在迅速改变着人们的生活方式。 经过我国改革开放多年…

中科数安 || 防止公司内部文件资料 \数据外泄,图档透明加密防泄密软件,源代码防泄露系统。

#文件防泄密软件# 中科数安是一家专注于信息安全领域的高科技企业&#xff0c;其提供的防止公司内部文件资料及数据外泄的解决方案主要包括图档透明加密和源代码防泄露系统等核心服务。 中科数安 | 图档、源代码防止外泄系统 PC地址&#xff1a; www.weaem.com 1. 图档透明加…

软考中级 --网络工程师真题试卷 2023下半年

在EIGRP协议中&#xff0c;某个路由器收到了两条路径到达目标网络&#xff0c;路径1的带宽为100Mbps&#xff0c;延迟2ms&#xff0c;路径2的带宽为50Mbps&#xff0c;迟为4ms&#xff0c;如果EIGRP使用带宽和延迟的综合度量标准&#xff0c;那么该路由器选择的最佳路径是(D)。…