构造函数和析构函数及类中指针成员变量的new和delete

一直对于C++的继承机制非常疑惑,今天专门研究了一下继承过程中构造函数、虚构函数、以及对于构造函数初始化的一些问题。入的坑,还望大家少走弯路。

构造函数中new内存分配及析构函数delete

大家都知道,当程序中创建一个类指针对象并将其初始化的时候,只要该类有指针成员变量,且在构造函数中利用new操作符为该指针变量分配堆块上的内存时,我们就需要实时注意需要手动管理该段内存的释放。函数中用delete操作符对创建的类对象进行删除和释放类对象内存的时候,需要在析构函数函数体中对该指针成员变量所占用的内存释放掉,若是指针对象则用delete object,若是指针数组,则用delete[] object。

但是有一个问题是,若是具有形参的构造函数对该类初始化的时候,在构造函数中不仅需要将为该指针成员变量分配内存,还需要将构造函数的传参内容逐个复制到动态分配的内存中来。如下Base类及其源码实现:

class Base

{

public:

    Base(char *n);

    virtual ~Base();

private:

    char *name;

};

Base::Base(char*n)

{

    name = new char[20];

    strcpy(name,n);

    cout<<"Baseclass constructor..."<<endl;

}

Base::~Base()

{

    delete[] name;

    cout<<"Baseclass destructor..."<<endl;

 

}

我们在Base类中定义了name指针变量,在Base构造函数中为name分配20个char类型的连续内存,并利用strcpy函数将构造函数传参n逐字复制到name中,这是为什么呢?为什么不直接name=n,直接赋值,多省事?非也!

因为在函数中的局部变量均是存储在栈上的,我们知道栈上的内存在函数调用结束后,系统就自动将其内存释放,name=n只是将n数据所在的内存地址告诉了name,构造函数调用结束后,栈上的n数据早已经被系统释放了,再次调用析构函数对name所指的内存进行释放就会释放已经被释放的栈上内存,就会出错,便会出现_BLOCK_TYPE_IS_VALID(pHead->nBlockUse字样的corruption,至于详细解释,请参考博客(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse问题解析)。

虚析构函数bug

我们知道构造函数不能是虚函数,因为构造函数还没实现的情况下是不能使用多态性的。而析构函数大多时候需要声明为虚函数,若基类的析构函数不是虚函数,则当声明了基类指针指向派生类对象释放该指针时只会调用基类的析构函数,因此也只会释放掉基类对象指向的内存部分,而析构函数声明为virtual的话,则delete指针的时候,则会首先调用派生类的析构函数,接着调用基类的析构函数,完全释放掉该指针对象所指向内存。


猜你喜欢

转载自blog.csdn.net/qq_18548149/article/details/78942015