C++ 多态的一些注意点

2022/3/4 14:45:46

本文主要是介绍C++ 多态的一些注意点,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

virtual

对于虚方法(virtual method),如果一个方法是通过引用或者指针而不是对象调用的,它将确定使用哪一种方法。如果没有使用关键字virtual,程序将根据引用类型或指针类型选择方法;如果使用了virtual,程序将根据引用或指针指向的对象的类型来选择方法

基类通常声明虚析构函数

这样做是为了确保释放派生对象时,按正确的顺序调用析构函数。如果不是虚的,那么销毁指向派生类对象的基类指针在销毁的时候只会调用基类的析构函数,而不会调用派生类的,从而导致数据无法被正确析构。如果是虚的,那么将先调用派生类的析构函数,然后再自动调用基类的析构函数。

静态联编和动态联编

函数名联编:将源代码中的函数调用解释为特定的函数代码块;

在C++中,由于函数重载的缘故,这项任务更复杂,编译器必须乍看函数参数及函数名才能确定使用哪个函数。
C/C++编译器可以在编译过程完成上述联编。

静态联编(早起联编):在编译过程中完成的联编;

但虚函数的存在使得这项工作变得更加复杂,有虚函数的情况下,使用哪一个函数是不能在编译时确定的,应为编译器不知道用户将选择哪种类型的对象,所以编译器必须生成能够在程序运行时选择正确虚函数的代码。

动态联编(晚期联编):在程序运行时进行的联编。

向上强制转换(upcasting):将派生类引用或指针转换为基类引用或指针;(不需要显式类型转换)
向下强制转换(downcasting):将基类指针或引用转换为派生类指针或引用;(需要强制类型转换)

Derived a;
Base *p1 = &a;  // OK
Base &p2 = a;   // OK

Base b;
Derived *p3 = &b;  // Wrong
Derived *p4 = (Base *)(&b); // OK

向上强制转换(upcasting)可以将派生类引用或指针转换为基类引用或指针并隐式调用派生类或基类方法,此时就需要动态联编;

class B
{
    virtual void do_f(); // private member
public:
    void f() { do_f(); } // public interface
};
 
struct D : public B
{
    void do_f() override; // overrides B::do_f
};
 
int main()
{
    D d;
    B* bp = &d;
    bp->f(); // internally calls D::do_f();
}
比较 效率 处理阶段
动态联编 需要跟踪指针或引用,有额外开销 运行时
静态联编 效率更高 编译时


这篇关于C++ 多态的一些注意点的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程