zoukankan      html  css  js  c++  java
  • 使用 C++ 多态时需要注意的问题

    本文为大便一箩筐的原创内容,转载请注明出处,谢谢:http://www.cnblogs.com/dbylk/


    最近工作中遇到一些关于使用多态的细节问题,在此记录一下。



    ## 一、多态和模板匹配 模板是 C++ 在编译过程中使用的特性,而多态是程序运行时期的特性,因此,想要让多态作用于模板匹配是不可能的。
    // Author :大便一箩筐 2016-04-03
    
    template<typename T>
    void OutputTypeName(const Type& object)
    {
        cout << typeid(T).name() << endl;              // 错误的例子,模板匹配不支持多态
        cout << typeid(object).name() << endl;         // 正确的例子
    } 
    

    Ps:要想让 typeid 正确工作,需要启用编译器的 RTTI 选项(会对程序性能有一定的影响,在 MSVC 中默认开启),否则程序会运行报错。
    RTTI,全称 Run-Time Type Information,运行时类型信息。具体来说就是支持在程序运行的过程中,通过 typeid 获取多态对象的实际类型(注意,一定要是多态对象,没有定义虚函数的类型无法让 RTTI 正确工作)。


    ## 二、多态与多重继承 在多重继承中使用多态时,作为指针类型的基类中一定要定义虚函数。 ``` // Author :大便一箩筐 2016-04-03

    class Base
    {
    public:
    ~Base();
    void Output() { cout << "A" << endl; }
    int nData;
    }

    class FirstDerive : public Base
    {
    public:
    virtual ~FirstDerive();
    virtual void Output() { cout << "B" << endl; }
    float fData;
    }

    class SecondDerive : public FirstDerive
    {
    public:
    ~SecondDerive();
    void Output() { cout << "C" << endl; }
    char cData;
    }

    void main()
    {
    Base* pBase = new SecondDerive(); // 错误的用法,Base中没有定义虚函数
    pBase->Output(); // 输出结果为“A”
    delete pBase; // 这一步会造成内存访问错误

    FisrtDerive* pFirstDerive = new SecondDerive();      // 正确的用法
    pFirstDerive ->Output();                             // 输出结果为“C”
    delete pFirstDerive ;                                // 正确的用法
    

    }

    1. 输出结果错误产生的原因很简单,因为 Base 中没有定义虚函数,所以编译器并没有为它建立虚函数映射表,所以使用 Base 指针无法访问到子类中定义的虚函数。
    2. delete pBase 报错,个人猜测可能的原因是 pBase 指针前存放了指向 SecondDerive 类型的 type_info 的指针,因此释放时需要调用 free( pBase - 4 ),而由于编译器并不知道 pBase 指向了 SecondDerive 类型的对象,也就是不知道 type_info 指针的存在,所以直接调用了 free( pBase ) 导致堆内存访问错误。(暂时没有时间深究这个问题,猜想的正确性留待以后验证)
  • 相关阅读:
    【leetcode】1295. Find Numbers with Even Number of Digits
    【leetcode】427. Construct Quad Tree
    【leetcode】1240. Tiling a Rectangle with the Fewest Squares
    【leetcode】1292. Maximum Side Length of a Square with Sum Less than or Equal to Threshold
    【leetcode】1291. Sequential Digits
    【leetcode】1290. Convert Binary Number in a Linked List to Integer
    【leetcode】1269. Number of Ways to Stay in the Same Place After Some Steps
    【leetcode】1289. Minimum Falling Path Sum II
    【leetcode】1288. Remove Covered Intervals
    【leetcode】1287. Element Appearing More Than 25% In Sorted Array
  • 原文地址:https://www.cnblogs.com/dbylk/p/5350316.html
Copyright © 2011-2022 走看看