美文网首页
C++类 继承

C++类 继承

作者: Mr_约科 | 来源:发表于2019-10-10 15:00 被阅读0次

    1. 父类指针指向子类对象

    • 虚函数的作用主要是实现了多态的机制。
    • 可以用父类的指针指向其子类,然后通过父类的指针调用实际子类的成员函数。
    • 仅仅可调用父类含有的虚函数,非父类函数不能调用

    (1)普通虚函数调用

    virtual 实现了父类的虚函数被子类的同名函数替换,实现了通过父类调用子类函数的功能。

    class CFather
    {
    public:
        CFather(void)
        {
        }
        ~CFather(void)
        {
        }
        virtual void PrintOut(void)
        {
            cout << "父类PrintOut" << endl;
        }
    };
    
    class CSon : public CFather
    {
    public:
        CSon(void)
        {
        }
        ~CSon(void)
        {
        }
        void PrintOut(void)
        {
            cout << "子类PrintOut" << endl;
        }
    };
    
    int main()
    {
        CFather* father = new CSon();
        father->PrintOut();//输出:子类PrintOut
        cout << "Hello World!" << endl;
        return 0;
    }
    

    (2)构造和析构函数的调用

    构造析构 实例化方式
    先父类构造后子类构造 父类指针指向子类对象 等号右边new 子类
    先父类构造后子类构造 子类指针指向子类对象 等号右边new 子类
    先子类析构后父类析构 释放 子类指针指向子类对象
    先子类析构后父类析构 释放 父类指针指向子类对象 (父类析构加virtual)
    只父类析构 释放 父类指针指向子类对象 (父类析构无virtual)
    a 父类析构函数为非虚函数
        CFather(void)
        {
            cout << "父类构造" << endl;
        }
        ~CFather(void)
        {
            cout << "父类析构~" << endl;
        }
        CSon(void)
        {
            cout << "子类构造" << endl;
        }
        ~CSon(void)
        {
            cout << "子类析构~" << endl;
        }
    
        int main()
        {
            CFather* father = new CSon();
            father->PrintOut();
            delete father;
            cout << "Hello World!" << endl;
            return 0;
        }
    

    输出结果:
    父类构造
    子类构造
    子类PrintOut
    父类析构~
    Hello World!

    • 析构时由于父类的析构函数为非虚函数,所以未调用子类的析构函数。
    • 若子类的构造函数存在动态内存分配,则会存在内存泄漏的问题。
    b 父类析构函数为虚函数
        virtual ~CFather(void)
        {
            cout << "父类析构~" << endl;
        }
    

    输出结果:
    父类构造
    子类构造
    子类PrintOut
    子类析构~
    父类析构~
    Hello World!

    (3)父子类指针强制转换的安全性

    a 父类指针强制转换为子类指针

    one

    class CFather
    {
    public:
        CFather(void)
        {
            cout << "父类构造" << endl;
        }
        ~CFather(void)
        {
            cout << "父类析构~" << endl;
        }
        void PrintOut(void)
        {
            cout << "父类PrintOut" << endl;
        }
    };
    
    class CSon : public CFather
    {
    public:
        CSon(void)
        {
            cout << "子类构造" << endl;
        }
        ~CSon(void)
        {
            cout << "子类析构~" << endl;
        }
        void PrintOut(void)
        {
            cout << "子类PrintOut" << endl;
        }
    };
    
    int main()
    {
        CFather *father = new CFather();
        CSon* son = static_cast<CSon*>(father);
        son->PrintOut();
        delete son;
        cout << "Hello World!" << endl;
        return 0;
    }
    

    输出结果:
    父类构造
    子类PrintOut
    子类析构~
    父类析构~
    Hello World!

    将父类中与子类的同名函数定义为虚函数
    将父类的析构函数定义为虚函数
    结果反而不去调用子类的同名函数与析构函数
    示例如下所示:

        virtual ~CFather(void)
        {
            cout << "父类析构~" << endl;
        }
        virtual void PrintOut(void)
        {
            cout << "父类PrintOut" << endl;
        }
    

    输出结果:
    父类构造
    父类PrintOut
    父类析构~
    Hello World!

    two

    class CFather
    {
    public:
        CFather(void)
        {
            cout << "父类构造" << endl;
        }
        virtual ~CFather(void)
        {
            cout << "父类析构~" << endl;
        }
        virtual void PrintOut(void)
        {
            cout << "父类PrintOut" << endl;
        }
    };
    
    class CSon : public CFather
    {
    public:
        CSon(void)
        {
            cout << "子类构造" << endl;
        }
        ~CSon(void)
        {
            cout << "子类析构~" << endl;
        }
        void PrintOut(void)
        {
            cout << "子类PrintOut" << endl;
        }
    };
    
    int main()
    {
        CFather *father = new CSon();
        CSon* son = static_cast<CSon*>(father);
        son->PrintOut();
        delete son;
        cout << "Hello World!" << endl;
        return 0;
    }
    

    输出结果:
    父类构造
    子类构造
    子类PrintOut
    子类析构~
    父类析构~
    Hello World!

    b 子类指针强制转换为父类指针

    2. 子类指针指向父类对象

    综上,对于C++继承个人建议

    • 父类名* cptr = new 子类名()
    • 定义父类中与子类同名的函数为虚函数
    • 定义父类析构函数为虚函数
    • 手动delete cptr

    3. 函数形参为父类,实参为子类

    相关文章

      网友评论

          本文标题:C++类 继承

          本文链接:https://www.haomeiwen.com/subject/xuvkuctx.html