即使通过普通的按值调用参数传递机制将对象传递给函数,理论上它们可以保护和隔离调用参数,但是仍然可能发生可能影响甚至损坏的副作用,用作参数的对象.例如,如果用作参数的对象分配内存并在销毁时释放该内存,那么在调用析构函数时,函数内部的本地副本将释放相同的内存.这将使原始物体损坏并且实际上无用.
这是用C++编写的:完整参考
在这个程序在这里
#include<iostream>
using namespace std;
class Sample
{
public:
int *ptr;
Sample(int i)
{
ptr = new int(i);
}
~Sample()
{
cout<<"destroyed";
delete ptr;
}
void PrintVal()
{
cout << "The value is " << *ptr;
}
};
void SomeFunc(Sample x)
{
cout << "Say i am in someFunc " << endl;
}
int main()
{
Sample s1= 10;
SomeFunc(s1);
s1.PrintVal();
}
Run Code Online (Sandbox Code Playgroud)
它会在对象s1从对象返回时被销毁时生成运行时错误.我无法弄清楚为什么会发生这种情况,因为应该制作副本.我想也许是因为班级定义中没有复制构造函数.但我很惊讶地发现,如果使用这个函数声明
void SomeFunc(Sample &x)
{
cout << "Say i am in someFunc " << endl;
}
Run Code Online (Sandbox Code Playgroud)
在此声明中不会发生错误.不应该在这里发生错误,因为它被引用了吗?谁能解释两种情况都会发生什么.
JBL*_*JBL 11
这确实是因为您没有提供复制构造函数.因此,编译器将为您生成一个,这将执行简单的复制.这就是指针的微不足道的副本,这里有问题.
对于以下声明
void SomeFunc(Sample x);
Run Code Online (Sandbox Code Playgroud)
传递s1给函数时确实会有一个副本,但是这个副本将有一个指针的副本,也就是说,两个对象将指向相同的副本int.
然后,当退出该函数时,副本将被销毁并将删除该指针,将原始对象留在调用代码中,并且指针刚刚删除(记住,它们指向同一个东西).
然后,为以下声明
void SomeFunc(Sample &x);
Run Code Online (Sandbox Code Playgroud)
你没有任何副本,因此问题没有出现.实际上,通过引用传递意味着在函数内部,Sample您正在操作的对象与传递给函数的对象完全相同,并且在函数退出时不会被销毁.
| 归档时间: |
|
| 查看次数: |
4314 次 |
| 最近记录: |