今天下午在研究虚函数的时候遇到了一个问题,觉得很有意思,记录一下。
先看代码:
class Base
{
public:
Base(int value)
{
m_nValue = value;
cout << "object(" << this << "){" << this->m_nValue << "} is constructing!" << endl;
} ~Base()
{
cout << "object(" << this << "){" << this->m_nValue << "} is destroy!" << endl;
}
private:
int m_nValue;
}; int main()
{
Base b();
(Base)b;
return ;
}
打印结果:
为什么会调用两个析构函数?一个析构函数是可以理解的,为什么要调用两次?
其实这里是调用了一次拷贝构造函数。调整一下代码
class Base
{
public:
Base(int value)
{
m_nValue = value;
cout << "object(" << this << "){" << this->m_nValue << "} is constructing!" << endl;
}
//新增部分
Base(const Base& b)
{
this->m_nValue = b.m_nValue;
cout << "object(" << this << "){" << this->m_nValue << "} is copy constructing!" << endl;
}
//新增部分结束!
~Base()
{
cout << "object(" << this << "){" << this->m_nValue << "} is destroy!" << endl;
}
private:
int m_nValue;
}; int main()
{
Base b();
(Base)b;
return ;
}
执行结果:
注意红框里边标注的!(Base)b隐式的调用了拷贝构造函数和析构函数。
(Base)b的操作这样看起来不是很舒服,我们把再修改一下代码
void fun(Base b)
{
//do nothing
}
int main()
{
Base b();
fun(b);
return ;
}
执行结果:
b在进入fun这个函数的时候,发生了拷贝构造到析构的操作。这样就很容易理解刚开始的问题:为什么会出现两次析构函数。
再修改一下代码,验证一下:
void fun(Base& b)
{
//do nothing
cout << "fun" << endl;
}
int main()
{
Base b();
fun(b);
return ;
}
执行结果。
这也就是为什么要用引用 Base& b 而直接使用 Base b 的原因了。当然,最好还是加上const。
上述就是这个问题的记录