C++中多态要注意的事情&与Java的对比

101 篇文章 1 订阅

注:下面是我自己最近看书的总结,应该有错误


在C++中,如果子类与父类的函数名相同,那么子类将覆盖父类中同名的函数,也就是说,在继承关系中,方法签名只由方法名决定。若想实现多态效果,那么只能使用虚函数来实现。父类中的虚函数可能被编译为一个指针,编译子类时将子类相应的函数地址赋值给那个指针。


我想,继承在向上和向下两个方向起作用:

向上:子类可以使用父类中public和protected的方法和变量,实现代码重用。

向下:父类中的虚函数由不同的子类实现,实现多态。


在这个模型中,容易出问题的地方应该在“覆盖”上。子类对象赋值给父类变量后,执行的是父类中的函数,而不是自身的函数。这样一是容易使人陷入困惑,二是增大了对象的体积。所以我认为在设计时要尽量避免这种情况。如果是特意追求这种效果,一定要在注释中对此进行说明。

例如下面的代码:

#include <iostream>
using namespace std;


class Base
{
        public:
        virtual void f(float x){cout << "Base::f(float)" << x <<endl;}  
                void g(float x){cout << "Base::g(float)" << x <<endl;}
                void h(float x){cout << "Base::h(float)" << x <<endl;}
};
class Derived:public Base
{
        public:
                void f(float x){cout << "Derived::f(float)" << x << endl;}
                void g(int x){cout << "Derived::g(int)" << x << endl;}
                void h(float x, float y){cout << "Derived::h(float, float)" << x << y <<endl;}  
};


int main(void){
        Derived d;

        d.f(3.14);
        d.g(3.14);
        d.h(3.14);


        return 0;
}
在编译时就会报错:

BaseDerived.cpp: In function ‘int main()’:
BaseDerived.cpp:26:10: error: no matching function for call to ‘Derived::h(double)’
BaseDerived.cpp:26:10: note: candidate is:
BaseDerived.cpp:16:8: note: void Derived::h(float, float)
BaseDerived.cpp:16:8: note:   candidate expects 2 arguments, 1 provided

说明父类中的g(int)和h(float)被“覆盖”了。

这与Java中是不一样的,Java中只是函数名相同不会覆盖,而是实现了“重载”,例如:

class Base{
        public void f(double x){System.out.println("Base.f(double):" + x);}
        public void g(double x){System.out.println("Base.f(double):" + x);}     
}

class Derived extends Base{
        public void f(int x){System.out.println("Derived.f(int): " + x);}
        public void g(double x, double y)       {System.out.println("Derived.f(double, double): " + x + " " + y);}
}
class BaseDerived{
        public static void main(String args[]){
                
                Derived d = new Derived();

                d.f(3.14);
                d.g(3.14);
        }
}
运行结果:

Base.f(double):3.14
Base.f(double):3.14

说明尽管子类中定义了同名的f(int)和g(double, double),但父类中的f(double)和g(double)仍能使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值