我写了一个简单的 vector 类,它重载了赋值和加法运算符。该代码将两个 vector 相加并打印相加前后的 vector 。令人惊讶的是,在 c=a+b 行之后调用了析构函数 ~MyVector()。我不明白为什么会这样,因为对象 a、b 和 c 都没有超出范围。你了解调用析构函数的原因吗?
#include<iostream>
#include<cstdlib>
using namespace std;
template<typename T>
class MyVector
{
public:
MyVector(int s)
{
size=s;
a=new T[s];
}
~MyVector()
{
delete[] a;
size=0;
};
void freeVec()
{
cout<<"Calling destructor. a[0]= "<<a[0]<<endl;
if(a!=NULL)
{
free(a);
a=NULL;
}
}
int getSize(void)
{
return size;
}
void setSize(int ss)
{
size=ss;
}
T &operator[](int i)
{
return a[i];
}
MyVector &operator=(MyVector mv)
{
if(this==&mv)
return *this;
for(int i=0;i<mv.getSize();i++)
this->a[i]=mv[i];
this->size=mv.getSize();
return *this;
}
MyVector operator+(MyVector &mv)
{
for(int i=0;i<size;i++)
{
this->a[i]+=mv[i];
}
cout<<endl;
return *this;
}
private:
int size;
T *a;
};
int main(void)
{
MyVector<int> a(3),b(3),c(3);
a[0]=1;a[1]=2;a[2]=3;
b[0]=4;b[1]=5;b[2]=6;
cout<<"initial vector"<<endl;
for(int i=0;i<3;i++)
cout<<a[i]<<" ";
cout<<endl;
for(int i=0;i<3;i++)
cout<<b[i]<<" ";
cout<<endl;
c=a+b;
cout<<"final vectors"<<endl;
for(int i=0;i<3;i++)
cout<<a[i]<<" ";
cout<<endl;
for(int i=0;i<3;i++)
cout<<b[i]<<" ";
cout<<endl;
for(int i=0;i<3;i++)
cout<<c[i]<<" ";
cout<<endl;
cout<<endl;
return 0;
}
最佳答案
您的 a + b
返回一个无名的临时对象,该对象随后被复制到 c
(通过赋值运算符),然后被销毁。这就是您看到的析构函数调用。
此外,您的赋值运算符通过值 接收它的参数(为什么???),这意味着理论上也可以为此创建另一个拷贝。您的编译器显然优化了该拷贝,这就是为什么您只看到一个额外的析构函数调用的原因。
顺便说一句,由于您手动管理对象中分配的内存,因此根据“三原则”实现复制构造函数也是一个很好的主意。该类的当前版本(没有复制构造函数)可以很容易地用于构建损坏的代码,特别是因为缺少复制构造函数。事实上,您当前的代码已经损坏,因为它使用编译器提供的复制构造函数来复制您的类对象。您没有看到任何崩溃的唯一原因是因为编译器优化(删除)了大部分拷贝,并且可能是因为您很幸运。
最重要的是,您的二进制 +
实现修改了存储在 *this
对象中的数据(为什么???),这意味着 c = a + b
修饰 a
。这并不是人们期望看到的二进制 +
运算符的典型行为。
您的代码中还有许多其他奇怪的东西。例如,什么是 freeVec
以及为什么它试图在总是由 new[]
分配的内存上使用 free
?另外,为什么析构函数将 size
设置为 0
?这有什么意义?
关于c++ - 为什么调用析构函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18389749/