对C++多态的理解

多态

说的就是不同的对象收到相同的任务输出不同的结果。

静态多态

#include <iostream>

int sum(int a, int b) {
    return a + b;
}

double sum(double a, double b) {
    return a + b;
}

int main() {
    std::cout << sum(1,2) << std::endl;
    std::cout << sum(3.3, 2.9) << std::endl;
    return 0;
}

可以看到上述有两种sum函数,其中第一个为算两个整形数的和,第二个算小数的和。
静态多态就是在编译过程中,编译器会根据函数的类型、参数等情况来辨别应该使用哪个函数。
值得注意的是重载函数的返回值和参数是跟被重载的函数返回类型与参数类型不同的。

动态多态

#include <iostream>

class A {
public:
    A() {}
    void print() { std::cout << "A" << std::endl; }
};
class B : public A {
public:
    B() {}
    void print() { std::cout << "B" << std::endl; }
};
class C : public A {
public:
    C() {}
    void print() { std::cout << "C" << std::endl; }
};

int main() {
    A a;
    B b;
    C c;
    A* ptr_b = &b;
    A* ptr_c = &c;

    ptr_b->print();
    ptr_c->print();
    
    return 0;
}

运行上述代码,得到的结果都是输出A的,这是因为在定义ptr_bptr_c时虽然指向的是B对象和C对象的地址,但是因为编译器在编译时已经确定了使用基类的print()函数,所以只会输出A。这时我们可以使用动态多态的方法来解决此类问题。

#include <iostream>

class A {
public:
    A() {}
    virtual void print() { std::cout << "A" << std::endl; }
};

class B : public A {
public:
    B() {}
    void print() { std::cout << "B" << std::endl; }
};

class C : public A {
public:
    C() {}
    void print() { std::cout << "C" << std::endl; }
};

int main() {
    A a;
    B b;
    C c;

    A* ptr_b = &b;
    A* ptr_c = &c;

    ptr_b->print();
    ptr_c->print();

    return 0;
}

这时ptr_bptr_c指向的就是B的对象和C的对象了。查看类的大小会发现比原来的大了,这是因为有虚函数的类在实例化后会有虚函数表(vtable),而这个表是对每个该类的对象共享,也就是说该类的所有对象共用一个虚函数表。而这些对象通过虚表指针来判断自己的虚函数表。例如:

class A {
public:
    A() {}
    virtual void print1() { std::cout << "A->v1" << std::endl; }
    virtual void print2() { std::cout << "A->v2" << std::endl; }
};

class B : public A {
public:
    B() {}
    virtual void print1() { std::cout << "B->v1" << std::endl; }
    void fun() { std::cout << "B->B" << std::endl; }
};

class C : public B {
public:
    C() {}
    virtual void print2() { std::cout << "C->v2" << std::endl; }
    void fun() { std::cout << "C" << std::endl; }
};

可以看出A类有两个虚函数,那么实例化A类的话对象通过虚表指针会指向A类的虚函数。
实例化B类的话,B类对象的print1指向自己的虚函数表,print2指向A类的虚函数表。
实例化C类,C类对象的print2指向自己的虚函数表,print1指向B类的虚函数表。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值