【问题标题】:Why destructor is calling after function scope ending when object reference passed as parameter?当对象引用作为参数传递时,为什么析构函数在函数范围结束后调用?
【发布时间】:2012-06-05 11:38:24
【问题描述】:

为什么在函数(pass(s​​ample const &ob1))作用域结束后调用析构函数,当对象引用作为参数传递时?为什么它在函数 pass() 中创建一个新对象,而我们正在传递一个对象引用?

帮帮我,我遇到内存转储错误

#include<iostream>
using namespace std;


class sample
{
public:
    int *ptr;
    sample()    
    {
        cout<<"this is default constructor & addr  "<<this<<endl;
    }
    sample(int i)
    {
        cout<<"this is single parameter constructor & addr "<<this<<endl;
        ptr=new int[i];

    }
    void disp() 
    {
        cout<<"hello \n";
    }
    ~sample()
    {
        cout<<"destructor & addr "<<this;
        delete ptr;
    }

};



sample pass(sample const& ob1)
{

for(int i=0;i<5;i++)
    ob1.ptr[i]=10;
return ob1;

}

int main()
{   
sample obj(5);
sample copy;
cout<<"before calling \n";
obj.disp();
pass(obj);
copy.disp();
cout<<"after calling \n";
return 0;
}

【问题讨论】:

  • 您知道pass 正在返回一个副本吗?
  • delete ptr; 错了,应该是delete [] ptr; 因为你用的是new[]

标签: c++ pass-by-reference destructor


【解决方案1】:

那是因为你按值返回:

sample pass(sample const& ob1)
{
   //...
   return ob1;  
}

并且不保证会发生 RVO。在这种情况下,我什至不确定它会发生

【讨论】:

  • 我们必须做什么才能不调用该函数中的析构函数?
  • @sai 我看到你没有使用返回类型。所以不要返回任何东西。如果需要按值返回,则无法阻止。
【解决方案2】:

您正在按值返回sample;这涉及到sample 的构造和销毁(尽管在某些情况下它可以是optimised away)。

【讨论】:

  • 即使我没有返回任何值(我尝试了返回类型 void),同样的内存转储错误来了...
  • @sai:好的,但这是一个单独的问题。你应该阅读Rule of Three
  • 谢谢你,现在我知道了三个规则并且我用复制构造函数清除了,复制赋值运算符
【解决方案3】:

函数 pass() 正在创建一个新对象,因为该对象是按值返回的,而不是按引用返回的。 按值返回对象将调用复制构造函数,并创建一个新对象(临时对象),该对象将在函数返回时立即销毁。

为避免创建临时对象,请尝试通过引用返回对象。 此外,默认构造函数没有初始化整数指针,导致内存转储错误。

sample const& pass(sample const &ob1)
{

for(int i=0;i<5;i++)
ob1.ptr[i]=10;
cout << "pass & addr " << &ob1 << endl ;

return ob1;

}
sample()    
{
    cout<<"this is default constructor & addr  "<<this<<endl;
    this->ptr = new (int);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-10
    • 2014-01-16
    • 1970-01-01
    • 1970-01-01
    • 2016-09-26
    相关资源
    最近更新 更多