我对如何调用析构函数有疑问。例如,我创建了以下foo类,并提供了复制构造函数,析构函数和重载赋值运算符。我创建了这个foo对象的动态数组,并使用运算符“=”来分配数组的单个元素。我很困惑,在赋值操作后立即调用析构函数,当我想访问新分配的对象中的数据时,我得到了非常混乱的结果。有什么建议吗?
#include <iostream>
using namespace std;
bool debug = true;
class foo{
private:
int n;
void init(int _n);
public:
int* arr; // just to make it accessible so that we can tract the contents;
foo(int _n);
foo(int* _a, int len);
foo(const foo & rhs);
foo & operator=(const foo & rhs);
~foo();
};
void foo::init(int _n = 0){
n = _n;
arr = new int[n];
for(int i = 0; i != n; i++) arr[i] = 0;
}
foo::foo(int _n = 0){
init(_n);
}
foo::foo(int*_a, int len){
init(len);
for(int i = 0; i< len; i++) arr[i] = _a[i];
}
foo::foo(const foo &rhs){
operator = (rhs);
}
foo& foo::operator= (const foo &rhs){
if(debug) cout<<"\nassignment operator overloaded";
if (this != &rhs){
if(n != 0) {
n = rhs.n;
delete [] arr;
arr = new int[n];
for(int i = 0; i < n; i++) arr[i] = rhs.arr[i];
}
}
return *this;
}
foo::~foo(){
if (debug)cout << "\ndestructor called\n";
delete []arr;
}
int main(){
{ // a explicit block to see when the destructor is called;
foo* f = new foo[4];
int n = 4;
int a[] = {0,1,2,3};
for(int i = 0; i < n;i++) {
cout<<i;
f[i] = foo(a, i);
cout<<f[i].arr[i]<<"\n"; // result is some seemingly random number;
}
}
system("PAUSE");
}*
答案 0 :(得分:3)
执行此操作时:
f[i] = foo(a, i);
在赋值运算符的RHS上创建临时foo
对象。然后,它用于分配给运营商的LHS上的foo
。然后,它被销毁,因此它的析构函数被调用。
分配后垃圾值的原因可能是n
在数组中的所有0
中都是foos
。您的赋值运算符已损坏。您可能需要查看copy and swap idiom。
答案 1 :(得分:1)
一个大不禁!将未初始化对象的初始化委托给赋值运算符是个不错的主意:
foo::foo(const foo &rhs){
operator = (rhs);
}
更好的是:
foo::foo(const foo &rhs)
: n(rhs.n), arr(new int[n])
{
// copy rhs.arr to arr
}
// Note: Passing by value:
foo& operator = (foo rhs) {
std::swap(n, rhs.n);
std::swap(arr, rhs.arr);
return *this;
// Note: The swapped rhs will do the cleanup in the destructor
}
最终会减少编码和异常安全
另一个问题是:
cout&lt;&lt; f [i] .arr [i]&lt;&lt; “\ n” 个
您正在打印未定义的'结束'值(arr [i] == arr [n])