记录C++中,子类同名属性并不能完全覆盖父类属性的问题

问题代码:

        首先看一段代码:很简单,就是BBB继承自AAA,然后BBB重写定义了同名属性,然后调用父类AAA的打印函数:

#include <iostream>
using namespace std;class AAA {
public:AAA() {}~AAA() {}void func() {YourVar = 20;}void print() {cout << "YourVar: " << YourVar << endl;}public:int YourVar = 10;};class BBB : public AAA {
public:BBB() {YourVar = 20;}~BBB() {}void print1() {cout << "YourVar: " << YourVar << endl;}void YourMethodOrFunction() {}private:int YourVar;
};int main() {BBB b;b.print();//b.print1();cout << "********" << endl;return 0;
}

打印结果:

        会发现,明明我构造函数里面将YourVar的值改为了20,但是还是打印的10.

        这个问题,属于C++的基础问题,我记得,子类继承父类,如果子类中,定义了同名属性的话,那么父类的属性会被隐藏,访问子类的那个属性,就是子类的,不会是父类的。

        但是如果父类里面,有一个打印的函数print,会发现,这个print函数,生效的范围,只有父类,不包括子类。只有将父类的print函数重写,才能生效在子类中:

解决思路1:重写print

#include <iostream>
using namespace std;class AAA {
public:AAA() {}~AAA() {}void func() {YourVar = 20;}void print() {cout << "YourVar: " << YourVar << endl;}public:int YourVar = 10;};class BBB : public AAA {
public:BBB() {YourVar = 20;}~BBB() {}void print() {cout << "YourVar: " << YourVar << endl;}void YourMethodOrFunction() {}private:int YourVar;
};int main() {BBB b;b.print();cout << "********" << endl;return 0;
}

打印结果:

虽然解决了问题,但是明明我父类中,写了print函数,干嘛还重新写一次?还有意义?

解决思路2:去掉子类的同名属性

#include <iostream>
using namespace std;class AAA {
public:AAA() {}~AAA() {}void func() {YourVar = 20;}void print() {cout << "YourVar: " << YourVar << endl;}public:int YourVar = 10;};class BBB : public AAA {
public:BBB() {YourVar = 20;}~BBB() {}//private:
//	int YourVar;
};int main() {BBB b;b.print();cout << "********" << endl;return 0;
}

但是有时候,我们就是要这么重写,那么该怎么办呢?

解决思路3:将父类地址传递给子类

#include <iostream>
using namespace std;class AAA {
public:AAA() {YourVar = new int;*YourVar = 10;}~AAA() {delete YourVar;}void print() {cout << "YourVar: " << *YourVar << endl;}protected:int *YourVar;
};class BBB : public AAA {
public:BBB() {// 将父类地址传递给子类YourVar = AAA::YourVar;*YourVar = 20;}~BBB() {}private:int *YourVar;
};int main() {BBB b;b.print();cout << "********" << endl;return 0;
}

解决思路4:将子类地址传递给父类:

#include <iostream>
using namespace std;class AAA {
public:AAA() {// YourVar = new int;// *YourVar = 10;}~AAA() {delete YourVar;}void print() {cout << "YourVar: " << *YourVar << endl;}protected:int *YourVar;
};class BBB : public AAA {
public:BBB() {YourVar = new int;// 将子类地址传递给父类AAA::YourVar = YourVar;*YourVar = 20;}~BBB() {}private:int *YourVar;
};int main() {BBB b;b.print();cout << "********" << endl;return 0;
}

总结

1. 面对这样的情况,要么就不要写同名属性(但有时候不能保证自己忘记了)

2. 当以后继承的类层次很多的时候,难免会定义同名属性,但是父类的函数,是不会访问子类的同名属性的,这个是这个问题的关键。虽然在子类中,父类的属性确实是隐藏了,但隐藏不代表消失,也不代表父类的函数中,也将这个属性给隐藏或者替换了。

3. 要么就使用指针,将父类和子类的地址变成一样的地址。

4. 虽然最后一种比较麻烦,但是会惊奇的发现,如果是指针的话,可以实现父类中实现所有操作,子类只管创建对象和使用,子类如果想改实现,根据需要同名替代即可。甚至属性也可以写成函数指针那些,是一种非常灵活的使用方式,是一种上层设计模式的简单体现。

#include <iostream>
using namespace std;class AAA {
public:AAA() {// YourVar = new int;// *YourVar = 10;}~AAA() {delete YourVar;}void print() {cout << "YourVar: " << *YourVar << endl;}protected:int *YourVar;
};class BBB : public AAA {
public:BBB() {YourVar = new int;// 将子类地址传递给父类AAA::YourVar = YourVar;*YourVar = 20;}~BBB() {}void print() {cout << "*********************" << endl;cout << "YourVar: " << *YourVar << endl;cout << "*********************" << endl;}private:int *YourVar;
};int main() {BBB b;b.print();return 0;
}

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

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

相关文章

145 Linux 网络编程1 ,协议,C/S B/S ,OSI 7层模型,TCP/IP 4层模型,

一 协议的概念 从应用的角度出发&#xff0c;协议可理解为“规则”&#xff0c;是数据传输和数据的解释的规则。 典型协议 传输层 常见协议有TCP/UDP协议。 应用层 常见的协议有HTTP协议&#xff0c;FTP协议。 网络层 常见协议有IP协议、ICMP协议、IGMP协议。 网络接口层 常…

NLP 笔记:LDA(训练篇)

1 前言&#xff1a;吉布斯采样 吉布斯采样的基本思想是&#xff0c;通过迭代的方式&#xff0c;逐个维度地更新所有变量的状态 1.1 举例 收拾东西 假设我们现在有一个很乱的屋子&#xff0c;我们不知道东西应该放在哪里&#xff08;绝对位置&#xff09;&#xff0c;但知道哪…

【排序算法】实现快速排序值(霍尔法三指针法挖坑法优化随即选key中位数法小区间法非递归版本)

文章目录 &#x1f4dd;快速排序&#x1f320;霍尔法&#x1f309;三指针法&#x1f320;挖坑法✏️优化快速排序 &#x1f320;随机选key&#x1f309;三位数取中 &#x1f320;小区间选择走插入&#xff0c;可以减少90%左右的递归&#x1f309; 快速排序改非递归版本&#x1…

设计模式及其在项目、框架中的应用

设计模式的作用&#xff1a; 1、类之间关系图&#xff0c;明确的角色及其关系、作用&#xff1b; 2、符合开闭原则&#xff0c;职责明确&#xff0c;并且开放的拓展点可以有效应对后期的变化。 &#xff08;一&#xff09;、责任链模式 适用场景&#xff1a; 在一个流程中&…

【QT入门】 Qt实现自定义信号

往期回顾&#xff1a; 【QT入门】图片查看软件(优化)-CSDN博客 【QT入门】 lambda表达式(函数)详解-CSDN博客 【QT入门】 Qt槽函数五种常用写法介绍-CSDN博客 【QT入门】 Qt实现自定义信号 一、为什么需要自定义信号 比如说现在一个小需求&#xff0c;我们想要实现跨ui通信&a…

Git 使用笔记

基本操作&#xff1a; 初始化 &#xff08;git init&#xff09; 使用背景和作用&#xff1a; 在本地建立一个文件夹后&#xff0c;基于这个文件夹进行git 操作&#xff0c;赋予git操作本文件夹的权限 。查看当前文件夹状态&#xff08;git status&#xff09; 每次打开文件夹…

环信新版单群聊UIKit集成指南——Android篇

前言 环信新版UIKit已重磅发布&#xff01;目前包含单群聊UIKit、聊天室ChatroomUIKit&#xff0c;本文详细讲解Android端单群聊UIKit的集成教程。 环信单群聊 UIKit 是基于环信即时通讯云 IM SDK 开发的一款即时通讯 UI 组件库&#xff0c;提供各种组件实现会话列表、聊天界…

机器学习:智能时代的核心引擎

目录 一、什么是机器学习 二、监督学习 三、无监督学习 四、半监督学习 五、强化学习 一、什么是机器学习 机器学习是人工智能的一个分支&#xff0c;它主要基于计算机科学&#xff0c;旨在使计算机系统能够自动地从经验和数据中进行学习并改进&#xff0c;而无需进行明确…

鸿蒙Harmony应用开发—ArkTS(stateStyles:多态样式)

Styles和Extend仅仅应用于静态页面的样式复用&#xff0c;stateStyles可以依据组件的内部状态的不同&#xff0c;快速设置不同样式。这就是我们本章要介绍的内容stateStyles&#xff08;又称为&#xff1a;多态样式&#xff09;。 概述 stateStyles是属性方法&#xff0c;可以…

CodeSys创建自定义的html5控件

文章目录 背景创建html5control.xml文件控件界面以及逻辑的实现使用的资源安装自定义的html5控件库 背景 查看官方的资料&#xff1a;https://content.helpme-codesys.com/en/CODESYS%20Visualization/_visu_html5_dev.html 官方的例子&#xff1a;https://forge.codesys.com/…

【机器学习入门 】逻辑斯蒂回归和分类

系列文章目录 第1章 专家系统 第2章 决策树 第3章 神经元和感知机 识别手写数字——感知机 第4章 线性回归 文章目录 系列文章目录前言一、分类问题的数学形式二、最大似然估计三、交叉熵损失函数四、多类别分类多类别逻辑斯蒂回归归一化指数函数交叉熵误差和均方误差的比较 五…

MySQL、Oracle的时间类型字段自动更新:insert插入、update更新时,自动更新时间戳。设置自增主键id,oracle创建自增id序列和触发器

1. MySQL 支持设置自增id的字段类型&#xff1a;int、bigint、double等数值类型&#xff0c;一般用int、bigint支持设置自动更新时间的字段类型&#xff1a;datetime、timestamp下面sql中的now()函数可以用current_timestamp()替代 1.1. 不指定秒精度 drop table if exists …

【蓝桥杯-单片机】基于定时器的倒计时程序设计

基于定时器的倒计时程序 题目如下所示&#xff1a; 实现过程中遇到的一些问题 01 如何改变Seg_Buf数组的值数码管总是一致地显示0 1 2 3 4 5 首先这个问题不是在main.c中关于数码管显示部分的逻辑错误&#xff0c;就是发生在数码管的底层错误。 检查了逻辑部分&#xff…

【C++庖丁解牛】二叉搜索树(Binary Search Tree,BST)

&#x1f341;你好&#xff0c;我是 RO-BERRY &#x1f4d7; 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f384;感谢你的陪伴与支持 &#xff0c;故事既有了开头&#xff0c;就要画上一个完美的句号&#xff0c;让我们一起加油 目录 1. 二叉搜索树概念2. 二叉…

python框架的一加剧场管理系统的设计与实现flask-django-nodejs-php

本文讲述了一加剧场管理系统。结合电子管理系统的特点&#xff0c;分析了一加剧场管理系统的背景&#xff0c;给出了一加剧场管理系统实现的设计方案。 本论文主要完成不同用户的权限划分&#xff0c;不同用户具有不同权限的操作功能&#xff0c;在用户模块&#xff0c;主要有用…

letcode::根据二叉树创建字符串

根据二叉树创建字符串 题目描述&#xff1a; 给你二叉树的根节点 root &#xff0c;请你采用前序遍历的方式&#xff0c;将二叉树转化为一个由括号和整数组成的字符串&#xff0c;返回构造出的字符串。 空节点使用一对空括号对 “()” 表示&#xff0c;转化后需要省略所有不影…

一文读懂SDRAM内存模组与基本概念

本文可以了解什么&#xff1f; DDR-DDR4内存模块的差异以及对比&#xff1b;逻辑BANK的概念与定义&#xff1b;芯片的位宽的解释。 下图是DDR3的PHY IP Core的定义规范。 DDR-DDR4的物理结构差异 首先&#xff0c;我们来对比一下DDR, DDR2, DDR3 SDRAM, and DDR4 SDRAM物理…

cyclictest 交叉编译报错---rt_numa.h:18:10: fatal error: numa.h: 没有那个文件或目录

cyclictest 主要是用于测试系统延时&#xff0c;进而判断系统的实时性 使用版本 rt-tests-2.6.tar.gz numactl v2.0.16 问题 编译时&#xff0c;需要先编译 numactl &#xff0c;不然会有以下报错&#xff1a; arm-linux-gnueabihf-gcc -D VERSION2.6 -c src/cyclictest/c…

FPGA——DDR3的IP核

FPGA——DDR3的ip核 IP核配置基于MIG核代码基于AXI接口的DDR3 IP核配置 1 2 3 4 5 6 基于MIG核代码 控制MIG核的信号进行读写 module MIG_APP_Drive(input i_ui_clk ,input i_ui_rst ,input init_calib_…

数字孪生底层技术框架

数字孪生是一种将现实世界中的物理实体、过程或系统数字化并映射到计算机模型中的方法。它在数学建模与仿真方面具有重要作用&#xff0c;为了实现数字孪生&#xff0c;以下是一些底层技术框架和方法&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业…