47记-C++继承引起的父子之间的冲突

xiaoxiao2025-12-09  5

47记-C++继承引起的父子之间的冲突

思考2个问题

子类中是否可以定义父类中的同名成员和同名函数?如果可以,如何区分?如果不可以,为什么?

子类中定义的函数是否能重载父类中的同名函数?

带着这两个问题来做下试验,试试就知道了,电脑又不会爆炸。


同名成员变量的测试
#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 究竟是子类自定义的,还是从父类继承得到的? //回答:此时调用的是Child类的成员变量mi, //为什么呢? //因为如果父类的已经成员变量mi而还在子类再定义一个和父类同名的成员变量mi //那么说明子类需要一个新的成员变量来覆盖隐藏父类的成员变量 c.Parent::mi = 1000; //那么如果要对父类的成员变量进行操作,则使用作用域分辨符(::)来访问父类就可以了 return 0; }
所以对于第一个问题可以得出的结论是

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

子类中的成员将隐藏父类中的同名成员(这种现象称为同名覆盖)

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

子类可以通过**作用域分辨符(::)**访问父类中的同名成员


对于第二个问题的测试试验

对于重载,重载有3点

重载函数的本质为多个不同的函数函数名和参数列表是唯一的标识函数重载必须发生在同一个作用域中

当了解了这三点就能够愉快的进行试验了。

#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; /*//1.首先屏蔽着两个成员函数,其目的是测试子类是否能重载父类的成员函数add 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; /*2.当屏蔽了1.的代码时,此时编译时会出错, 错误信息为子类对象c找不到add(int)和add(int,int)这两个函数。 为什么找不到了呢?因为子类如果定义了和父类同名的函数时 则会将父类的同名成员函数隐藏起来,用子类的函数将其覆盖。 那么为解决这个错误,就需要这样调用 c.Parent::add(1); c.Parent::add(2, 3); c.add(4, 5, 6); 这样调用就能够使用父类的成员函数, 而此时计算的mi的值又是谁的成员变量mi呢? cout << "c.mi = " << c.mi << endl; cout << "c.Parent::mi = " << c.Parent::mi << endl; 这两段代码输出的结果为 c.mi = 100; c.Parent::mi = 1006; 为什么会是使用父类的成员变量mi呢, 因为在父类中由于作用域的关系的成员函数不可能知道外部是否会有mi, 编译器就只能在父类的作用域中查找mi并且使用它。 所以这种现象表明,子类无法重载父类的同名成员函数, 虽然是继承关系,但是作用域是无法继承而来的。 且不符合重载3点中的第三点。 */ //将1.注释掉的代码恢复后。此时就可以在子类中重载add函数了。 //而且此时add函数中操作的mi就是子类的成员变量mi了。 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; }

从这个实验中可以得出的结论是

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

子类无法重载父类中的成员函数

使用作用域分辨符可以访问父类中的成员函数

子类可以定义父类中完全相同的成员函数
转载请注明原文地址: https://www.6miu.com/read-5040575.html

最新回复(0)