美文网首页
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