构造析构与虚函数

new/delet    是C++编译器实现的关键字,以类型为单位分配,申请时可以初始化内存

malloc/free  是C库实现的函数,以字节为单位分配,并不会初始化内存

#include <iostream>
#include <string>
#include <cstdlib>

using namespace std;

class superclass
{
public:
    superclass()
    {  cout << "superclass constructor" << endl; }
    virtual ~superclass()
    {  cout << "superclass destructor" << endl;  }
};

class subclass : public superclass
{ 

};

int main()
{
    subclass* p_sub = new subclass;                              // 会触发构造函数
    subclass* p_sub_1 = (subclass *) mallloc(sizeof(subclass));  // 不会触发构造函数
    
    subclass* p_sub_2 = dynamic_cast<subclass*>(p_sub); 
    
    delete p_sub;   // 会触发析构函数
    free(p_sub_1);  // 不会触发析构函数
    
    return 0;
}

 

 

 构造函数不可能成为虚函数:在构造函数执行完后,虚函数表和虚函数表指针才会初始化。

 析构函数可以成为虚函数:尽量将析构函数声明为虚函数。(当定义指向子类的父类指针后,再delete父类指针时,子类的析构函数函数也会被调用,避免了内存泄漏。尽量把析构函数声明为虚函数)

 构造函数不可以发生多态行为:在构造函数之前,虚函数表指针还未初始化。

 析构函数不可以发生多态行为:在析构函数之前,虚函数表指针就被销毁。

构造函数和析构函数:调用当前类定义的虚函数,并不会发生多态的行为

#include <iostream>
#include <string>

using namespace std;

class superclass
{
public:
    superclass()   // 不可以声明为虚函数
    {       
        func();  // 构造函数中调用虚函数,不会发生多态,运行本类中的虚函数
    }
    virtual void func() 
    {
        cout << "superclass virtual function" << endl;
    }   
    virtual ~superclass()  // 尽量将析构函数声明为虚函数,防止未被调用而造成内存泄漏
    {
        func();  // 析构函数中调用虚函数,不会发生多态,运行本类中的虚函数
    }
};


class subclass : public surperclass
{
public:
    subclass()
    { 
        func();
    }
    virtual void func()
    {
        cout << "subclass virtual function" << endl;
    }
    ~subclass()
    {
        func();
    }
};


int main()
{
    superclass* p_super = new subclass();
       
    delete p_super;  

// 如果superclass 的虚构函数没有声明为虚函数,编译器会根据p_super的类型(superclass)调用superclass的析构函数,不会调用subclass的析构函数 // 当superclass的虚函数声明为虚函数,编译器会根据p_super指向的对象(subclass)来先调用subclass的析构函,再调用superclass的析构函数。 return 0; }

 

 

 

继承中的强制类型转换:

dynamic_cast用于有直接或间接继承关系的类的指针或引用之间的强制转换。

dynamic_cast要求:相关类中必须有虚函数,

指针:转换成功-->得到目标类型的指针。转换失败-->得到空指针。

引用:转换成功-->得到目标类型的应用。转换失败-->得到异常操作信息。

 

#include <iostream>
#include <string>

using namespace std;

class superclass
{
public:
    superclass()
    {
        cout << "superclass constructtor" << endl;
    }
    virtual ~superclass()  // 为了使用 dynmaic_cast 而声明成虚函数
    {
        cout << "superclass destructor" << endl;
    }
};

class subclass : public superclass
{

};

int main()
{
    superclass* p_super1 = new superclass;  
    subclass* p_sub1 = dynamic_cast<subclass*>(p_super1); // 不能用子类的指针指向父类,dynmaic_cast返回空指针
   
    superclass* p_super2 = new subclass;                
    subclass* p_sub2 = dynamic_cast<subclass*>(p_super2); // 不能用父类指针初始化子类指针,通过 dynamic_cast返回正确地址
    
    delete p;
    
    return 0;
}

 

 

  

posted @ 2019-05-13 15:23  张不源  Views(344)  Comments(0Edit  收藏  举报