0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C++之父子之间冲突的解决方法

电子设计 来源:电子设计 作者:电子设计 2020-12-24 15:59 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

一、父子之间的冲突:

1、思考

子类中是否可以定义父类中的同名成员?

如果可以的话,那么该怎样区分呢?

如果不可以的话,那么又是为啥呢?

代码实践:

#include <iostream>
#include <string>
using namespace std;
class Parent

public:
int mi;
};
class Child : public Parent

public:
int mi;
};
int main()

Child c;

c.mi = 100; // mi 究竟是子类自定义的,还是从父类继承得到的?

return 0;

代码是否可以编译通过,我们来看一下编译器编译的结果:

root@txp-virtual-machine:/home/txp# g++ test.cpp
root@txp-virtual-machine:/home/txp#

什么情况,居然可以编译情况,但是你从肉眼看,你看出到底是父类mi还是子类的mi呢,显然我们不能够去瞎猜,那么接下来我们来学习里面的真理!

2、父子之间冲突的规则:

子类可以定义父类中的同名成员

子类中的成员将隐藏父类中的同名成员

父类中的同名成员依然存在于子类中

通过作用域分辨符(::)访问父类中的同名成员,例如:

Child c;
c.mi = 100; //子类中的mi
c.Parent::mi = 1000; // 父类中的mi

代码实践:

#include <iostream>
#include <string>
using namespace std;
namespace A

int g_i = 0;

namespace B

int g_i = 1;// 同名的全局变量,但是位于两个不同的命名空间;

class Parent

public:
int mi;

Parent()

cout << "Parent() : " << "&mi = " << &mi << endl;

};
class Child : public Parent

public:
int mi;

Child()

cout << "Child() : " << "&mi = " << &mi << endl;

};
int main()

Child c;

c.mi = 100;

c.Parent::mi = 1000;

cout << "&c.mi = " << &c.mi << endl;
cout << "c.mi = " << c.mi << endl;

cout << "&c.Parent::mi = " << &c.Parent::mi << endl;
cout << "c.Parent::mi = " << c.Parent::mi << endl;

return 0;

输出结果:

root@txp-virtual-machine:/home/txp# g++ test.cpp
root@txp-virtual-machine:/home/txp# ./a.out
Parent() : &mi = 0x7ffc270e7bf0
Child() : &mi = 0x7ffc270e7bf4
&c.mi = 0x7ffc270e7bf4
c.mi = 100
&c.Parent::mi = 0x7ffc270e7bf0
c.Parent::mi = 1000

3、回顾重载:

(1)类中的成员函数可以进行重载

重载函数的本质为多个不同的函数

函数名和参数列表是唯一的标识

函数重载必须发生在同一个作用域中,这一点非常关键

(2)子类中定义的函数是否能够重载父类中的同名函数呢?

代码实践:

#include <iostream>
#include <string>
using namespace std;
class Parent

public:
int mi;

void add(int v)

mi += v;


void add(int a, int b)

mi += (a + b);

};
class Child : public Parent

public:
int mi;

void add(int v)

mi += v;


void add(int a, int b)

mi += (a + b);


void add(int x, int y, int z)

mi += (x + y + z);

};
int main()

Child c;

c.mi = 100;

c.Parent::mi = 1000;

cout << "c.mi = " << c.mi << endl;

cout << "c.Parent::mi = " << c.Parent::mi << endl;

c.add(1);
c.add(2, 3);
c.add(4, 5, 6);

cout << "c.mi = " << c.mi << endl;

cout << "c.Parent::mi = " << c.Parent::mi << endl;

return 0;

结果输出:

root@txp-virtual-machine:/home/txp# g++ test.cpp
root@txp-virtual-machine:/home/txp# ./a.out
c.mi = 100
c.Parent::mi = 1000
c.mi = 121
c.Parent::mi = 1000

注解:从实验观察来看,函数重名和成员重名的作用一样,子类会覆盖父类的。

为了更加说明这点,我们再来看一个示例:

#include <iostream>
#include <string>
using namespace std;
class Parent

public:
int mi;

void add(int v)

mi += v;


void add(int a, int b)

mi += (a + b);

};
class Child : public Parent

public:
int mi;



void add(int x, int y, int z)

mi += (x + y + z);

};
int main()

Child c;

c.mi = 100;

c.Parent::mi = 1000;

cout << "c.mi = " << c.mi << endl;

cout << "c.Parent::mi = " << c.Parent::mi << endl;

c.add(1);
c.add(2, 3);
c.add(4, 5, 6);

cout << "c.mi = " << c.mi << endl;

cout << "c.Parent::mi = " << c.Parent::mi << endl;

return 0;

编译结果:

root@txp-virtual-machine:/home/txp# g++ test.cpp
test.cpp: In function ‘int main()’:
test.cpp:47:12: error: no matching function for call to ‘Child::add(int)’
c.add(1);

test.cpp:47:12: note: candidate is:
test.cpp:29:10: note: void Child::add(int, int, int)
void add(int x, int y, int z)

test.cpp:29:10: note: candidate expects 3 arguments, 1 provided
test.cpp:48:15: error: no matching function for call to ‘Child::add(int, int)’
c.add(2, 3);

test.cpp:48:15: note: candidate is:
test.cpp:29:10: note: void Child::add(int, int, int)
void add(int x, int y, int z)

test.cpp:29:10: note: candidate expects 3 arguments, 2 provided

注解:显示匹配不到add(int)和add(int,int)这两个函数

解决方案,就是利用作用域符分辨符解决问题:

#include <iostream>
#include <string>
using namespace std;
class Parent

public:
int mi;
void add(int v)

mi += v;

void add(int a, int b)

mi += (a + b);

};
class Child : public Parent

public:
int mi;
void add(int x, int y, int z)

mi += (x + y + z);

};
int main()

Child c;
c.mi = 100;
c.Parent::mi = 1000;
cout << "c.mi = " << c.mi << endl;
cout << "c.Parent::mi = " << c.Parent::mi << endl;
c.Parent::add(1);
c.Parent::add(2, 3);
c.add(4, 5, 6);
cout << "c.mi = " << c.mi << endl;
cout << "c.Parent::mi = " << c.Parent::mi << endl;
return 0;

输出结果:

root@txp-virtual-machine:/home/txp# ./a.out
c.mi = 100
c.Parent::mi = 1000
c.mi = 115
c.Parent::mi = 1006

4、小结:

子类中的函数将隐藏父类的同名函数

子类无法重载父类中的成员函数(不在同一作用域里面)

使用作用域分辨符访问父类中的同名函数

子类可以定义类中完全相同的成员函数

二、总结

子类可以定义父类中的同名成员

子类中的成员将隐藏父类中的同名成员

子类和父类中的函数不能构造重载关系

子类可以定义父类中完全相同的成员函数

使用作用域分辨符访问父类中的同名成员或者函数

好了,今天的分享就到这里,如果文章中有错误或者不理解的地方,可以交流互动,一起进步。我是txp,下期见!

审核编辑:符乾江
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 可编程逻辑
    +关注

    关注

    7

    文章

    526

    浏览量

    45319
  • C++
    C++
    +关注

    关注

    22

    文章

    2122

    浏览量

    76731
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    CC++之间的联系

    1、语法兼容性: C++完全兼容C语言的语法,这意味着任何有效的C语言程序都可以直接在C++编译器下编译通过。 2、底层控制: C++
    发表于 12-11 06:51

    C语言和C++之间的区别是什么

    区别 1、面向对象编程 (OOP): C语言是一种面向过程的语言,它强调的是通过函数将任务分解为一系列步骤进行执行。 C++C语言的基础上扩展了面向对象的特性,支持类(class)、封装、继承
    发表于 12-11 06:23

    C++之父亲临北京,AI原生时代最值得参加的系统软件技术大会日程发布

    秉承"全球专家、卓越智慧"的理念,由 CSDN 与奇点智能研究院举办的「2025 全球 C++ 及系统软件技术大会」将于 12 月 12-13 日在北京金隅喜来登大酒店正式举办。
    的头像 发表于 12-05 15:47 131次阅读

    C/C++条件编译

    条件编译是一种在编译时根据条件选择性地包含或排除部分代码的处理方法。在 C/C++ 中,条件编译使用预处理指令 #ifdef、#endif、#else 和 #elif 来实现。常用的条件编译指令有
    发表于 12-05 06:21

    C++程序异常的处理机制

    1、什么是异常处理? 有经验的朋友应该知道,在正常的CC++编程过程中难免会碰到程序不按照原本设计运行的情况。 最常见的有除法分母为零,数组越界,内存分配失效、打开相应文件失败等等。 一个程序
    发表于 12-02 07:12

    IP地址冲突导致德国站群服务器断网的解决方法?

    在网络管理中,IP地址冲突是一个常见且令人头疼的问题。尤其是对于依赖站群服务器进行大规模网络操作的企业而言,IP冲突可能会导致整个服务器群组无法正常工作,从而造成严重的业务中断。本文将探讨如何解决因
    的头像 发表于 08-12 15:47 601次阅读

    C++ 与 Python:树莓派上哪种语言更优?

    广泛应用于树莓派项目中。然而,C++在性能要求极高的应用和底层硬件控制方面表现出色。两者之间的选择取决于项目需求和对编程的熟悉程度。嗯,这就是简短的答案,但读完后
    的头像 发表于 07-24 15:32 667次阅读
    <b class='flag-5'>C++</b> 与 Python:树莓派上哪种语言更优?

    主流的 MCU 开发语言为什么是 C 而不是 C++

    在单片机的地界儿里,C语言稳坐中军帐,C++想分杯羹?难喽。咱电子工程师天天跟那针尖大的内存空间较劲,C++那些花里胡哨的玩意儿,在这儿真玩不转。先说内存这道坎儿。您当stm32f4的256kRAM
    的头像 发表于 05-21 10:33 788次阅读
    主流的 MCU 开发语言为什么是 <b class='flag-5'>C</b> 而不是 <b class='flag-5'>C++</b>?

    使用C++中的CyAPI编写的应用程序上遇到了问题,求解决

    我在使用 C++ 中的 CyAPI 编写的应用程序上遇到了问题。 我将 XferData() 方法与其他所有端点类型一起使用,没有遇到任何问题。 但是,将其与 Endpoint0 一起使用会引发
    发表于 05-13 06:11

    iic协议常见故障及解决方法

    SDA和时钟线SCL)进行通信。I2C协议以其简单性和低功耗特性,在嵌入式系统中得到了广泛应用。 常见故障 通信失败 原因 :可能是由于总线冲突、设备地址错误、数据线或时钟线短路或断路。 解决方法 :检查总线连接,确保没有短路或
    的头像 发表于 02-05 11:38 4643次阅读

    无功补偿故障原因及解决方法

    无功补偿故障可能由多种原因引起,以下是一些常见的故障原因及其解决方法
    的头像 发表于 01-29 14:25 2657次阅读

    Spire.XLS for C++组件说明

    Spire.XLS for C++ 是一款专业的 C++ Excel 组件,可以用在各种 C++ 框架和应用程序中。Spire.XLS for C++ 提供了一个对象模型 Excel
    的头像 发表于 01-14 09:40 1315次阅读
    Spire.XLS for <b class='flag-5'>C++</b>组件说明

    电子焊接的常见问题及解决方法

    问题及解决方法: 焊点虚焊 原因分析 :虚焊是指焊点表面看似焊接良好,但实际上焊料与焊件之间没有形成良好的冶金结合。虚焊的原因可能是焊接时间过短、焊接温度过低、焊料质量差等. 解决方法 :延长焊接时间,确保焊料充分熔化
    的头像 发表于 01-09 10:28 1938次阅读

    gitee 常见问题及解决方法

    Gitee作为国内的代码托管平台,在使用过程中可能会遇到一些问题。以下是一些常见问题及其解决方法: 一、仓库创建与代码推送问题 仓库已存在远程配置 问题 :在尝试为已有项目添加远程仓库配置时,可能会
    的头像 发表于 01-06 10:06 2387次阅读

    常见接近开关故障及解决方法

    无法做出相应反应。 解决方法 : 检查电源 :确认接近开关的电源供应是否正常,电压是否在额定范围内。使用万用表测量电源电压,排除电源故障。 检查连接线路 :检查接近开关与控制系统之间的连接线路是否松动、断裂或短路。确
    的头像 发表于 12-16 09:24 4790次阅读