与构造函数一样,析构函数也是一种特殊的函数。构造函数在实例化对象时被调用,而析构函数 在对象销毁时自动被调用。
因为析构函数是在对象摧毁时自动调用 当前函数内(作用域)return 时会自动调用。
所以要注意浅复制时存在的问题
在一个程序中 如果创建一个 函数 参数为一个类 且存在 delete 的析构函数 会存在因为 析构函数产生的错误
#include <iostream>
#include <string.h>
using namespace std;
class MyString
{
private:
char* buffer;
public:
MyString(const char* initString) // Constructor
{
buffer = NULL;
if(initString != NULL)
{
buffer = new char [strlen(initString) + 1];
strcpy(buffer, initString);
}
}
~MyString() // Destructor
{
cout << "Invoking destructor, clearing up" << endl;
delete [] buffer;
}
int GetLength()
{ return strlen(buffer); }
const char* GetString()
{ return buffer; }
};
void UseMyString(MyString str)
{
cout << "String buffer in MyString is " << str.GetLength();
cout << " characters long" << endl;
cout << "buffer contains: " << str.GetString() << endl;
return;
}
int main()
{
MyString sayHello("Hello from String Class");
UseMyString(sayHello);
return 0;
}
当程序运行时 因为函数 UseMyString(MyString str)
传入的参数为对象本身,UseMyString(sayHello);
传入的类 sayHello 被赋值给 str 局部变量。 指向的时同一个类 所以str.buffer 和 satHello.buffer 指向同一个地址(内存)。所以在函数 UseMyString(MyString str)
运行完返回时 会调用 str 的析构函数 从而 sayHello.buffer 会被 delete掉
当 main函数运行完后 会有一个 return 但是当return 时会调用 sayHello的析构函数 delete sayHello.buffer 但是 str调用析构函数的时候 buffer 已经被 delete 所以会报错
Function(类做为参数) 这个时候 指向同一个 内存。
如果类带有指针变量,并有动态内存分配,则它必须有一个拷贝构造函数。
为了避免这个 错误 一般利用 复制构造函数 传入 类的引用 然后将申请的
#include <iostream>
#include <string.h>
using namespace std;
class MyString
{
private:
char* buffer;
public:
MyString() {}
MyString(const char* initString) // constructor
{
buffer = NULL;
cout << "Default constructor: creating new MyString" << endl;
if(initString != NULL)
{
buffer = new char [strlen(initString) + 1];
strcpy(buffer, initString);
cout << "buffer points to: 0x" << hex;
cout << (unsigned int*)buffer << endl;
}
}
MyString(const MyString& copySource) // Copy constructor
{
buffer = NULL;
cout << "Copy constructor: copying from MyString" << endl;
if(copySource.buffer != NULL)
{
// allocate own buffer
buffer = new char [strlen(copySource.buffer) + 1];
// deep copy from the source into local buffer
strcpy(buffer, copySource.buffer);
cout << "buffer points to: 0x" << hex;
cout << (unsigned int*)buffer << endl;
}
}
// Destructor
~MyString()
{
cout << "Invoking destructor, clearing up" << endl;
delete [] buffer;
}
int GetLength()
{ return strlen(buffer); }
const char* GetString()
{ return buffer; }
};
void UseMyString(MyString str)
{
cout << "String buffer in MyString is " << str.GetLength();
cout << " characters long" << endl;
cout << "buffer contains: " << str.GetString() << endl;
return;
}
int main()
{
MyString sayHello("Hello from String Class");
UseMyString(sayHello);
return 0;
}
复制构造函数
MyString(const MyString& copySource) // Copy constructor
{
buffer = NULL;
cout << "Copy constructor: copying from MyString" << endl;
if(copySource.buffer != NULL)
{
// allocate own buffer
buffer = new char [strlen(copySource.buffer) + 1];
// deep copy from the source into local buffer
strcpy(buffer, copySource.buffer);
cout << "buffer points to: 0x" << hex;
cout << (unsigned int*)buffer << endl;
}
}