c/c++ 继承与多态 子类隐藏父类的同名非虚函数
问题1:若类A里有公有成员方法int fcn(),类B公有继承类A,并类B里有公有成员方法int fcn(int),可以在用户代码里,用类B的对象调用类A的int fcn()吗??
不可以,编译出错,提示类B里没有int fcn()。
是不是感觉很奇怪,类B公有继承了类A,按理说,类A的公有成员,是可以通过类B的对象来调用的。
原因是:子类重载了父类的int fcn(),注意是名字相同,参数不一样。结果导致,对于类B的对象来说,隐藏了父类A的同名方法int fcn()
#include <iostream>
class Base{
public:
virtual int fcn(){
std::cout << "base fcn()" << std::endl;
}
};
class D1 : public Base{
public:
int fcn(int){//形参与Base的fcn不一致,所以隐藏了Base的fcn
std::cout << "D1 fcn(int)" << std::endl;
}
virtual void f2(){
std::cout << "D1 f2()" << std::endl;
}
};
class D2 : public D1{
public:
int fcn(int){//隐藏了D1::fcn(int)
std::cout << "D2 fcn(int)" << std::endl;
}
int fcn(){//覆盖了Base的虚函数fcn
std::cout << "D2 fcn()" << std::endl;
}
void f2(){//覆盖了D1的虚函数f2
std::cout << "D2 f2()" << std::endl;
}
};
int main(){
Base b;
D1 d1;
D2 d2;
//原因是:子类重载了父类的int fcn(),注意是名字相同,参数不一样。结果导致,对应类B的对象来说,隐藏了父类A的同名方法int fcn()
d1.fcn();//error,不可以,编译出错,提示类B里没有int fcn()。
}
修改方法:使用using
class D1 : public Base{
public:
using Base::fcn;//使用using后,就把Base里的,所有fcn为名字的成员方法,都引入到D1里面,所以就可以使用D1的对象来调用Base里的任何fcn为名字的成员方法了。
int fcn(){
std::cout << "D1 fcn()" << std::endl;
}
int fcn(int){//形参与Base的fcn不一致,所以隐藏了Base的fcn
std::cout << "D1 fcn(int)" << std::endl;
}
virtual void f2(){
std::cout << "D1 f2()" << std::endl;
}
};
问题2:若Base里有多个fcn方法(名字相同,参数不一样),那么如果在Base的子类,只打算覆盖某个Base的fcn方法,而且还想让Base类里其他没有被覆盖的fcn方法也可以被调用,那应该怎么办?
办法1:在子类里覆盖所有Base的fcn方法,在方法体里,直接调用Base::fcn,但是这样太麻烦了,每一个都要覆盖。有没有好的办法?
办法2:使用using。只需要在子类的public下,using Base::fcn,就达到了办法1的效果。
c/c++ 学习互助QQ群:877684253
本人微信:xiaoshitou5854
c/c++ 继承与多态 子类隐藏父类的同名非虚函数的更多相关文章
- 读书笔记 effective c++ Item 36 永远不要重新定义继承而来的非虚函数
1. 为什么不要重新定义继承而来的非虚函数——实际论证 假设我告诉你一个类D public继承类B,在类B中定义了一个public成员函数mf.Mf的参数和返回类型并不重要,所以假设它们都是void. ...
- c++ 子类,基类 中this指针 虚函数使用
笔记: 子类和基类 构造函数不显式时,的this指针相同..在QT中,如果父类基于QObject,那么构造子类时传入this指针,这样所有子类,父类,基类都是同一地址.delelater(),会del ...
- C++ 学习笔记 (六) 继承- 子类与父类有同名函数,变量
学习了类的继承,今天说一下当父类与子类中有同名函数和变量时那么程序将怎么执行.首先明确当基类和子类有同名函数或者变量时,子类依然从父类继承. 举例说明: 例程说明: 父类和子类有同名的成员 data: ...
- public、potected 、private继承下的子类对父类成员的访问情况
#include<iostream> #include<string> using namespace std; class parent{ protected: int m_ ...
- 《effective C++》:条款36——绝不重新定义继承而来的非虚函数
(1)当派生类中重写了基类的非虚函数时,这个时候这个函数发生的是静态绑定 下面中的代码中: 定义一个基类B,基类定义了函数fcm,fcm是非虚的函数. 定义一个派生类D,派生类重新定义了fcm. 当用 ...
- C#中子类对基类方法的继承、重写和隐藏
提起子类.基类和方法继承这些概念,肯定大家都非常熟悉.毕竟,作为一门支持OOP的语言,掌握子类.基类是学习C#的基础.不过,这些概念虽然简单,但是也有一些初学者可能会遇到的坑,我们一起看看吧. 子 ...
- Java:[面向对象:继承,多态]
本文内容: 继承 多态 首发时期:2018-03-23 继承: 介绍: 如果多个类中存在相同的属性和行为,可以将这些内容抽取到单独一个类中,那么多个类(子类)无需再定义这些属性和行为,只要继承那个类( ...
- C++ 多态、虚函数、虚析构函数
1.若某种语言只支持类但不支持多态,则只能称为基于对象,不能说是面向对象. 2.多态:向不同对象发送同一个消息,不同的对象会产生不同的行为,发送消息可以是调用函数等操作.函数重载.运算符重载都是多态. ...
- OC的封装、继承与多态
面向对象有三大特征:封装.继承和多态. 一.封装 封装是将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作和访问.简而言之,信息隐藏,隐 ...
随机推荐
- Java货币金额转换为大写形式
package com.test; import java.math.BigDecimal; /** * * * 数字转换为汉语中人民币的大写<br> * */ public class ...
- Oracle绝对秒数转换为时间戳
一般Oracle得到的时间格式为: 1970-01-05 01:23:56.297 为了计算两个时间的差值: 1970-01-05 01:23:56.297 与 1970-01-05 01:24:57 ...
- Mac下 .bash_profile 和 .zshrc 两者之间的区别
这是我碰到的需要 source 之后才能使用环境变量的问题,我就不细究了,说说我的看法. .bash_profile 中修改环境变量只对当前窗口有效,而且需要 source ~/.bash_profi ...
- .NET Core实战项目之CMS 第九章 设计篇-白话架构设计
前面两篇文章给大家介绍了我们实战的CMS系统的数据库设计,源码也已经上传到服务器上了.今天我们就好聊聊架构设计,在开始之前先给大家分享一下这几天我一直在听的<从零开始学架构>里面关于架构设 ...
- 『字符串模式匹配 KMP』
字符串模式匹配 我们要先了解一下问题是什么. 模式匹配是数据结构中字符串的一种基本运算,给定一个子串,要求在某个字符串中找出与该子串相同的所有子串,这就是模式匹配. KMP 然后我们来认识一下今天的主 ...
- Leetcode 10. 正则表达式匹配 - 题解
版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - L ...
- Node.js API 初解读(三)
目录 Node.JS API 初解读三 Node.JS API 初解读三 Version: NodeJs v6.2.0 一. DNS (Domain Name Server) [域名服务器] 1.简介 ...
- 从零开始学习PYTHON3讲义(八)列表类型跟冒泡排序
<从零开始PYTHON3>第八讲 前面我们见过了不少的小程序,也见过了不少不同类型的变量使用的方法.但目前我们涉及到的,还都是单个的变量和单个的立即数.以变量来说,目前我们见到的,基本都 ...
- SpringBoot入门教程(十三)CORS方式实现跨域
什么是跨域?浏览器从一个域名的网页去请求另一个域名的资源时,域名.端口.协议任一不同,都是跨域 . 跨域资源访问是经常会遇到的场景,当一个资源从与该资源本身所在的服务器不同的域或端口请求一个资源时,资 ...
- 线程安全(上)--彻底搞懂volatile关键字
对于volatile这个关键字,相信很多朋友都听说过,甚至使用过,这个关键字虽然字面上理解起来比较简单,但是要用好起来却不是一件容易的事.这篇文章将从多个方面来讲解volatile,让你对它更加理解. ...