ps:看书的时候总被复制构造函数,析构函数所困扰,动不动就”这时候,某某情况下调用复制构造函数(或析构函数)”,上网查了一些资料,查看了一些相关书籍,做了一些总结。
复制构造函数和析构函数的作用:
什么时候调用复制构造函数?
1,新建一个对象并将其初始化为同类现有对象时,复制构造函数都将被调用。这种情况很多,最常见的情况是将新对象显示地初始化为现有的对象。
2,当程序生成了对象副本时,编译器都将使用复制构造函数,具体的说,当函数按值传递对象或函数返回对象时。
具体实例可以参考博文:http://blog.csdn.net/Fredomyan/article/details/6709686
在此联系一个常见的面试题:
class A
{
private:
int value;
public:
A(int n) { value = n; }
A( A other ) { value = other.value; }
void Print() { std::cout << value << std::endl; }
};
int _tmain( int argc, _TCHAR* argv[] )
{
A a = 10;
A b = a;
b.Print();
return 0;
}
结果是:编译错误。因为复制构造函数A(A other)传入的参数是A的一个实例,把形参复制到实参会调用复制构造函数,但C++的标准不允许复制构造函数传值参数,所以将会编译出错。
解决办法:把构造函数修改为A(const A& other),也就是把传值参数改成常量引用。
什么时候调用析构函数?
1,如果创建的是静态存储类对象,则其析构函数将在程序结束时自动被调用。
2,如果创建的是自动存储类对象,则其析构函数将在程序执行完代码块时自动被调用。
3,如果对象是通过new创建的,则它将它驻留在栈内存或自由存储区中,当使用delete来释放内存时,其析构函数将自动被调用。
4,创建临时对象来完成特定的操作,在这种情况下,程序将在结束对该对象的使用时自动调用其析构函数。
比如:
CMyString& CMyString::operator = ( const CMyString &str )
{
if( this != &str )
{
CMyString strTemp( str );
char* pTemp = strTemp.m_pData;
strTemp.m_pData = m_pData;
m_pData = pTemp;
}
return *this;
}
这是一个为下面CMyString类型实现异常安全性的赋值运算符函数。
class CMyString
{
public:
CMyString( char* pData = NULL );
CMyString( const CMyString& str );
~CMyString( void );
private:
char* m_pData;
};
由于strTemp是一个局部变量,但程序运行到if的外面时也就出了该变量的作用域,就会自动调用strTemp的析构函数,把strTemp.m_pData所指向的内存释放掉。