C++特性之多态

本文详细探讨了C++中的多态性,包括静态多态和动态多态的实现方式,以及如何通过虚函数实现运行时的多态。通过实例展示了多态在不同场景下的应用,并解释了虚函数、抽象类、虚表等概念,同时提醒在使用多态时应注意的事项。
摘要由CSDN通过智能技术生成



多态:向不同的对象发送同一个消息,不同的对象在接收时产生不同的行为(方法)

C++中,就是:不同功能的函数可以用同一函数名,这样就可以实现用一个函数名调用不同内容的函数。

例:学校校长通知:9.1日开学。不同的对象会做出不同的反应:教师需备好课;学生需按时到校上课;家长需备好学费 。由于事先对各种人的任务已做了规定,因此,在得到同一个消息时,各种人都知道怎么做。这就是多态。

  一、对象的类型

     1、静态类型:对象声明时的类型,在编译时确定。

     2、动态类型:目前所指对象的类型,在运行时确定。

class Base
{
};
 
class C:public Base
{
};
 
void Funtest()
{
Base b;
C d;
Base*pb1=&b;//编译器编译时就知道b的类型
pb1= &d;//只有程序运行后才知道d的类型
}
 
int main()
{
Funtest();
system("pause");
return 0;
}


  二、多态类型

      1、静态多态性(静态链编,早绑定):通过函数重载实现,要求程序在编译时就知道调用函数的全部信息。故又称为编译时多态性。

         优点:静态多态性的函数调用速度快、效率高

         缺点:缺乏灵活性,在程序运行前就已经决定了执行的函数和方法。

例:通过函数重载来实现:

int Add(int left, int right)
{
return left + right;
}
 
float Add(float left, float right)
{
return left + right;
}
 
void Funtest()
{
cout << Add(4, 6) << endl;//两个整数相加
cout << Add(2.32f,3.45f) << endl;//两个浮点数相加
}


如上代码,Add(4,6)Add(2.32f,3.45f)被分别编译为对Add(int ,int)Add(float,float)的调用。编译器会根据不同的参数列表对同名函数进行名字重整,之后这些同名函数就会变成拥有不同功能的函数。

运行结果如下:

带变量的宏也可以实现多态:

#define Add(a,b) (a)+(b)
int main()
{
int x = 4;
int y = 6;
float e = 2.32f;
float f = 3.45f;
cout << Add(x, y) << endl;
cout << Add(e, f) << endl;
system("pause");
return 0;
}


当程序被编译时,表达式Add(x,y)Add(e,f)被自动替换为两个整数相加和两个浮点数相加的具体表达式。运行结果如下:  

  

    动态多态性(动态链编,晚绑定):在程序执行期间判断所引用对象的实际类型,根据实际类型调用相应的方法。故又称为运行时的多态性。

     实现动态多态的条件:

  1.   (1)、派生类必须重写基类的虚函数。

      (2)、通过基类的指针/引用调基类的虚函数(该虚函数必须在派生类中被重写)

    class B
    {
    public:
    virtual void test1()
    {
    cout << "B::test1()" << endl;
    }
    virtual void test2()
    {
    cout << "B::test2()" << endl;
    }
        void test3()
    {
    cout << "B::test3()" << endl;
    }
    /*virtual void test4(int)
    {
    cout << "B::test4(int)" << endl;
    }*/
    virtual int test5()
    {
    cout << "B::test5()" << endl;
    }
    };
    class C :public B
    {
    public:
    virtual void test1()
    {
    cout << "C::test1()" << endl;
    }
        void test2()//重写虚函数,基类中的函数必须有virtual,派生类可以不加virtual
    {
    cout << "C::test2()" << endl;
    }
    virtual void test3()//没有构成重写
    {
    cout << "C::test3()" << endl;
    }
    /*virtual void test4()//重写:函数名、返回值类型、参数列表必须相同
    {
    cout << "C::test4()" << endl;
    }*/
    virtual void test5()//重写虚函数返回类型有误(协变)
    {
    cout << "C::test5()" << endl;
    }
    };
    void Funtest(B &b)
    {
    b.test1();
    b.test2();
    b.test3();
    //b.test4();
    b.test5();
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值