C++ 中的值传递
这里的对象是按值传递的,我不明白程序的输出。
#include <iostream>
using namespace std;
class Sample
{
public:
int *ptr;
Sample(int i)
{
ptr = new int(i);
}
~Sample()
{
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();
}
Here the object is passed by value, i don't understand the output of the program.
#include <iostream>
using namespace std;
class Sample
{
public:
int *ptr;
Sample(int i)
{
ptr = new int(i);
}
~Sample()
{
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();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您忘记编写复制构造函数。编译器会为您生成一个,它仅复制指针的值,而不进行深层复制。因此,当您传递的参数被复制并销毁时,您的原始对象会尝试在同一指针上第二次调用delete,这是未定义的行为。
请记住三法则。
简而言之:
如果您需要定义
复制构造函数
、复制赋值运算符
或析构函数
中的一个,那么您可能需要定义另一个也有两个。在这种情况下,您的复制构造函数
应如下所示:You have forgotten to write a copy-constructor. The compiler generates one for you which just copies the value of the pointer, not doing a deep copy. So, when the parameter you pass gets copied and destroyed, your original object tries to call delete the second time on the same pointer, which is undefined behavior.
Remember the Rule of Three.
In brief:
If you've a need to define either of
copy-constructor
,copy-assignment operator
ordestructor
, then you probably want to define the other two as well. In this case yourcopy constructor
should look something like this:我想象这里的输出应该是崩溃。
这里的问题是,当您按值传递时,您的 Sample 对象会被复制。在复制的对象中,您没有分配新的 ptr。所以当s1的副本被破坏时,就会删除原来的s1。
在下面添加一个复制构造函数以获得您想要的行为。
The output here should be a crash I'd imagine.
The problem here is that when you pass by value your Sample object is copied. In your copied object you're not allocating a new ptr. So when the copy of s1 is destructed, it will delete the original s1.
Add a copy constructor below to get your desired behavior.
问题
编译器提供的类中的默认复制构造函数仅复制指针而不是指针指向的整数。现在你有两个指向同一个对象的指针。当其中一个对象超出范围时,另一个对象内的指针将成为
悬空指针
。尝试访问悬空指针几乎总是会在运行时给您带来麻烦,例如使程序崩溃。解决方案
如果有任何类成员指针指向堆分配的缓冲区,则需要显式重载复制构造函数和赋值运算符=来深度复制这些指针成员,即分配新内存并复制数据这些指针指向。
Problem
The default copy constructor in your class provided by the compiler just copies the pointer instead of the integer that pointer points to. So now you have two pointers pointing to a single object. When one of the objects goes out of scope, the pointer inside the other object becomes
dangling pointer
. Trying to accessing a dangling pointer will almost always trouble you at run-time, like crashing your program.Solution
If you have any class member pointer points to a heap-allocated buffer, you need to explictly overload copy constructor and assignment operator= to deep copy those pointer members, i.e., allocate new memory and copy the data those pointers point to.
问题是你的类包含一个指针。
实际代码很少需要包含 OWNED 指针。它们通常包装在一些实用程序类(如智能指针或容器)中,或者更常见的是它们是简单的对象。
您的代码应该如下所示:
如果您需要动态分配的对象,那么它应该位于智能指针中(假设您想要共享资源,那么它看起来像这样。
假设您正在编写自己的指针包装器(坏主意),但是让我们假设它是用于指针练习,那么您需要遵守三规则,这是因为编译器生成的复制构造函数和赋值运算符不会执行正确的操作。 拥有的RAW的东西OWNED RAW 指针是您拥有的指针,因此负责删除
此问题有两种解决方案:将复制构造函数和赋值运算符设为私有。 ,所以我认为这不是你想要的,所以我们需要让它们工作,因为上面的 std::shared_ptr<> 涵盖了共享情况,我们将在这里介绍制作副本的非共享情况。
The problem is your class contains a pointer.
It is very rare for real code to need to contain
OWNED
pointers. They are usually wrapped in some utility class (like a smart pointer or a container) or more usually they are simple objects.Your code should look like this:
If you need a dynamically allocated object then it should be in a smart pointer (assuming you want a shared resource then it looks like this.
Assuming you are writing your own pointer wrapper (bad idea), but lets assume it is for practice with pointers. Then you need to obey the rule of three. This is because the compiler generated versions of
copy constructor
andassignment operator
will not do the correct thing for OWNED RAW pointers. an OWNED RAW pointer is an a pointer that you own and are thus responcable for deleting.There are two solutions to this problem. Make the copy constuctor and assignment operators private. This will stop your code working, so I assume that is not what you want. So we need to make them work. Since the shared case is covered above by std::shared_ptr<> here we will cover the non shared case of making copies.