• 个人编程笔记 - 子类和父类有同名的成员?


    前言

    面向对象编程的三个基本特征:封装、继承和多态。子类和父类有同名的成员?会出现什么样的行为。

    内容

    如果父类和子类都有一个成员,返回哪一个?

    case 1:没有虚函数,没有多态 => 通过父类的指针输出的是父类的值

    class Base {
    public:
    	Base() : value(10) {}
    	int getValue() { return value; }
    	int value;
    };
    class Sub :public Base {
    public:
    	Sub() : value(20) {}
    	int getValue() { return value; }
    	int value;
    };
    
    int main()
    {
    	Base* pBase = new Sub();
    	std::cout << "pBase->value:" << pBase->value << ", " << pBase->getValue() << std::endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    结果:
    在这里插入图片描述
    case 2: 有虚函数,有多态 => 通过父类的指针输出的是父类的value,和子类的 getValue;通过子类的指针输出的是子类的value,和子类的getValue。

    class Base {
    public:
    	Base() : value(10) {}
    	virtual int getValue() { return value; } // 虚函数
    	int value;
    };
    class Sub :public Base {
    public:
    	Sub() : value(20) {}
    	int getValue() { return value; }
    	int value;
    };
    
    int main()
    {
    	Base* pBase = new Sub();
    	// pBase->getValue() 调用的是 Sub::getValue。Sub::getValue 返回的是 Sub::value。
    	std::cout << "pBase->value:" << pBase->value << ", " << pBase->getValue() << std::endl;
    	Sub* pSub = dynamic_cast<Sub*>(pBase);
    	if (pSub)
    	{
    		std::cout << "pSub->value:" << pSub->value << ", " << pSub->getValue() << std::endl;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    结果:
    在这里插入图片描述
    注意:如果父类接口没有虚函数,即没有 virtual,不能使用 dynamic_cast

    如果函数本身被 const 修饰,本质上就是两个函数

    class Base {
    public:
    	Base() : value(10) {}
    	virtual int getValue() const { return value; } // 这里有 const 修饰符
    	int value;
    };
    
    class Sub :public Base {
    public:
    	Sub() : value(20) {}
    	int getValue() { return value; } // 这里没有 const 修饰符
    	int value;
    };
    
    int main()
    {
    	Base* pBase = new Sub();
    	std::cout << "pBase->value:" << pBase->value << ", " << pBase->getValue() << std::endl; // 都是父类的
    	Sub* pSub = dynamic_cast<Sub*>(pBase);
    	if (pSub)
    	{
    		std::cout << "pSub->value:" << pSub->value << ", " << pSub->getValue() << std::endl; // 都是子类的
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    结果:
    在这里插入图片描述
    注意:
    成员函数是否带 const,是两个不同的函数。

    class Base {
    public:
    	Base() : value(10) {}
    	virtual int getValue() const { return value; }
    	virtual int getValue() { return value; }
    	int value;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  • 相关阅读:
    推进高校学生党建工作数字化建设的思考
    Nuxt - 解决引入 qrcodejs2.js / QRCode.js 报错(document is not defined)
    Vue-点击 li 动态添加class -->[练]
    【性能测试】Jenkins+Ant+Jmeter自动化框架的搭建思路
    ARCGIS 横向图例是怎么做的?
    vue与C#实现自定义表单审批流程构建-后端
    在docker容器中 运行docker命令no such file
    成为一个合格程序员所必备的三种常见LeetCode排序算法
    使用jQuery实现简易商城系统
    Unity游戏Mod/插件制作教程05 - 插件实例2: 简单功能实现
  • 原文地址:https://blog.csdn.net/weixin_44153630/article/details/126451448