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