C++ 关于对象数组中的析构函数

C++ 关于对象数组中的析构函数,c++,arrays,C++,Arrays,我有一个关于如何调用析构函数的问题。例如,我创建了以下foo类,并提供了复制构造函数、析构函数和重载赋值运算符。我创建了一个这个foo对象的动态数组,并使用操作符“=”分配数组中的单个元素。我很困惑,在赋值操作之后,析构函数立即被调用,当我想访问新赋值对象中的数据时,我得到了非常混乱的结果。有什么建议吗 #include <iostream> using namespace std; bool debug = true; class foo{ private: int n

我有一个关于如何调用析构函数的问题。例如,我创建了以下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");
}*

#包括
使用名称空间std;
bool debug=true;
福班{
私人:
int n;
void init(int_n);
公众:
int*arr;//只是为了使其可访问,以便我们可以跟踪内容;
富(国际),;
foo(int*_a,int len);
foo(const foo&rhs);
foo和操作员=(常量foo和rhs);
~foo();
};
void foo::init(int\u n=0){
n=\u n;
arr=新整数[n];
对于(inti=0;i!=n;i++)arr[i]=0;
}
foo::foo(int\u n=0){
init(_n);
}
foo::foo(int*_a,int len){
init(len);
对于(int i=0;i
f[i] = foo(a, i);
在赋值操作符的RHS上创建一个临时
foo
对象。然后,它被用来赋值给操作符的LHS上的
foo
。然后,它被销毁,因此它的析构函数被调用

赋值后出现垃圾值的原因可能是数组中所有
foo
中的
n
0
。赋值运算符已损坏。执行此操作时,您可能需要查看。

f[i] = foo(a, i);
在赋值操作符的RHS上创建一个临时
foo
对象。然后,它被用来赋值给操作符的LHS上的
foo
。然后,它被销毁,因此它的析构函数被调用


赋值后出现垃圾值的原因可能是数组中所有
foo
中的
n
都是
0
。赋值运算符已损坏。您可能需要查看。

一个大的“否”!将未初始化对象的初始化委托给赋值运算符不是一个好主意:

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
}
您最终将获得更少的编码和异常安全性

另一个问题是:


coutA big no no no!将未初始化对象的初始化委托给赋值运算符不是一个好主意:

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
}
您最终将获得更少的编码和异常安全性

另一个问题是:


我是否已经修复了解构器的用法,使其在构建对象之后可以使用。我已经修复了解构器的用法,使其在构建对象之后可以使用。感谢您的输入,但我尝试根据您的建议修改代码,我仍然得到了类似的结果有线数字。还有什么建议吗?@宣州的另一个问题是“我明白了。如果我能在输入的开始阶段仔细考虑一下,但我试图根据你的建议修改我的代码,我仍然得到了类似的有线数字。还有什么建议吗?@宣州的另一个问题是“我明白了。如果我能思考的话。”它从一开始就成功了