按位复制构造函数是否真的与对象共享相同的内存位置?[关闭]

Does bitwise copy constructor really share same memory location for objects? [closed]

提问人:CREATIVITY Unleashed 提问时间:8/31/2023 最后编辑:273KCREATIVITY Unleashed 更新时间:9/3/2023 访问量:111

问:


想改进这个问题吗?通过编辑这篇文章添加详细信息并澄清问题。

3个月前关闭。

嘿,我对 C++ 中对象按位复制期间的内存分配感到困惑。 以下是Herbert Schildt C++第四版Pg:366的书所说的话:

让我们首先重述复制构造函数的问题 旨在解决。默认情况下,当使用一个对象进行初始化时 另一个是 C++ 执行按位复制。也就是说,相同的副本 初始化对象是在目标对象中创建的。虽然这个 在许多情况下是完全足够的,而且通常正是你 希望发生 - 在某些情况下,按位复制不应发生 被使用。最常见的一种情况是当对象分配内存时 创建时。例如,假设一个名为 MyClass 的类 在创建每个对象时为每个对象分配内存,并且对象 A 那个班级。这意味着 A 已经分配了其内存。 此外,假设 A 用于初始化 B,如下所示:MyClass B = A;

如果执行按位复制,则 B 将是 A 的精确副本。这意味着 B 将使用同一块分配的内存 A 正在使用,而不是分配自己的。显然,事实并非如此 期望的结果。例如,如果 MyClass 包含析构函数 释放内存,然后释放相同的内存 当 A 和 B 被摧毁时两次!

因此,我假设如果 A 和 B 都使用相同的内存,则在 A 中所做的任何更改都应该在 B 对象中发生更改,即使在内存分配后也是如此。所以我尝试了以下代码,我有 OBJ1 和 OBJ2 以及 OBJ1 按位复制以初始化 OBJ2。但是,如果更改 obj1 (id) 的私有成员,则 obj2 的 id 也应该更改,但事实并非如此。

这是我尝试过的代码:

#include <iostream>
using namespace std;
class Sample {


public:
int id;
void init(int x) {
id = x;
}
void display() {
cout << endl << "ID=" << id;
}
};

int main()
{
Sample obj1;
obj1.init(10);
obj1.display();

// Implicit Copy Constructor Calling
Sample obj2 (obj1);
obj2.display();
cout<<"change"<<endl;
obj1.id=33;
cout<<"value of id inside obj1";
obj1.display();
cout<<" \n value of id inside obj2";
obj2.display();
return 0;

// or obj2 = obj1;

}

输出如下:output

教科书真正想说什么?

C++ 内存 复制构造函数

评论

4赞 Yksisarvinen 8/31/2023
请不要上传代码/数据/错误的图像。
2赞 Jeffrey 8/31/2023
One of the most common is when an object allocates memory when it is created.这本书提到了对象包含指向 stuff 的指针的情况
7赞 molbdnilo 9/1/2023
几十年来,希尔德一直因其糟糕的书而臭名昭著。
1赞 Jeffrey 9/1/2023
您显示的示例没有指针。你需要包含类似的东西SampleOtherObject* other;
2赞 Pete Becker 9/1/2023
回复:“C++执行按位复制” - 不,这是大错特错的。默认的复制构造函数复制每个元素;如果元素的类型具有复制构造函数,则复制构造函数用于复制该元素。

答:

2赞 Klaus 9/1/2023 #1

你只是误解了“对象的记忆”和“对象分配的记忆”。

这意味着 B 将使用与 A 正在使用的相同的已分配内存,而不是分配自己的内存。

这意味着,如果类 A 分配了一些内存,例如,使用并持有指向该内存的指针,则类 B 的指针也将指向 A 分配的相同内存。按位复制将仅复制指针本身,不会自动分配新内存,也不会将指向 A 的内存内容也复制到分配给 B 的内存。最后一种被称为“深拷贝”。new

所以请看一下和.你会在网络上找到很多信息。deep copyshallow copy

我相信没有必要在这个答案中写一个新的额外例子,因为周围有数百万人!

3赞 Krzysztof Skowronek 9/1/2023 #2

所以,我真的不知道C++,但我知道答案:)

问题出在外部指针上。所以,如果你的类有字段:

class Sample {
   int just_int;
   int * int_pointer;

   sample(){
     int_pointer = new int; // allocation of "external" memory
   }

   ~sample(){
     delete int_pointer;
   }
}

默认复制构造函数将正确复制对象“内部”的所有值,因此 和 都将被复制。just_intint_pointer

但是,现在,该类的两个实例将指向 member 中的同一地址,这将导致问题。int_pointer

您必须编写复制构造函数来复制 - 指向的内存,或者根据需要执行任何需要的操作。int_pointer

这个问题在其他编程语言中很常见,你可以谷歌“深拷贝与浅拷贝”。默认的复制构造函数只做“浅层复制”,如果需要,你可以让它“深”化。