我想问的是,当我不显式地编写任何复制构造函数时,编译器会自动生成复制构造函数,默认情况下它执行浅拷贝,对吗?因此,在main()程序中,当我更改整数a、b和指针p的值时,p的值发生了变化,而a和b的值在复制的对象中保持不变。为什么a&b的值也没有变化?我的代码是:
#include <iostream>
#include <string.h>
using namespace std;
class Dummy {
private:
int a, b;
int *p;
public:
Dummy() {
p = new int;
}
void setData(int x, int y, int z) {
a = x;
b = y;
*p = z;
}
void showData() {
cout << "a = " << a << " b = " << b;
cout << " p = " << *p << endl;
}
~Dummy() {
delete p;
}
};
int main() {
Dummy d1;
d1.setData(3, 4, 5);
Dummy d2 = d1;
d1.showData();
d2.showData();
d1.setData(6, 7, 8);
d1.showData();
d2.showData();
return 0;
}我的程序的输出是:
a = 3 b = 4 p = 5
a = 3 b = 4 p = 5
a = 6 b = 7 p = 8
a = 3 b = 4 p = 8我的意思是,当我更改对象d2的值时,对象d1的指针发生了变化,那么为什么对象d2的a&b值也没有变化呢?
此外,我在析构函数中使用delete关键字删除动态分配的指针:
~Dummy() {
delete p;
}但它破坏了我的程序。为什么会这样呢?
发布于 2020-08-02 19:59:41
你完全搞错了- The idea of shallow copy。实际上,c++本身没有任何被称为deep copy的东西。所以,把shallow copy叫做a bit wrong。而仅仅使用这些词,shallow copy也创造了大量的confusion。
现在,让我解释一下,当cpp执行initialization using assignment时会发生什么。cpp或c(同时复制结构)有一个名为bitwise copy的概念。在这个概念中,all the member variables of one object(struct object/class object - you can say either) is identically copied to another object。现在,就是totally wrong idea了,both objects point to same memory location。实际上,both object有他们的own memory location,当然,their variables占领different memory spaces。对于你,我已经写了一些关于记忆的测试。如果您只看到测试并输出,您就会完全理解:
#include <iostream>
#include <string.h>
using namespace std;
class Dummy {
int a, b;
int *p;
public:
Dummy() {
p = new int;
}
void setData(int x, int y, int z) {
a = x;
b = y;
*p = z;
}
void showData() {
cout << "a = " << a << " b = " << b;
cout << " p = " << *p << endl;
cout << endl; // an extra new line for readability of output
}
void showMemory() {
cout << "addr(a) = " << &a << " addr(b) = " << &b;
cout << " addr(p) = " << &p << endl;
}
~Dummy() {
*p = 100;
delete p;
}
};
// testing memory
void memoryTest() {
cout << "testing d1:" << endl;
Dummy d1;
d1.setData(3, 4, 5);
cout << "addr(d1) = " << &d1 << endl;
d1.showMemory();
cout << endl ;
cout << "testing d2:" << endl;
Dummy d2 = d1;
cout << "addr(d2) = " << &d2 << endl;
d2.showMemory();
}
int main() {
// memoryTest
memoryTest();
return 0;
}试验的结果是:
testing d1:
addr(d1) = 0x6dfed4
addr(a) = 0x6dfed4 addr(b) = 0x6dfed8 addr(p) = 0x6dfedc
testing d2:
addr(d2) = 0x6dfec8
addr(a) = 0x6dfec8 addr(b) = 0x6dfecc addr(p) = 0x6dfed0这清楚地表明,这两个对象d1和d2占用的内存完全不同。
现在,您可能还有另一个问题:那么,当我编写d2__? __时,为什么会同时影响d1和d1?
当您指定时,Dummy d2 = d1;,我们可能会说发生了如下情况(不过,在应用按位复制时,它实际上并不发生,只是为了清晰起见):
d2.p = d1.p因此,我们知道,d1.p和d2.p包含相同的内存位置(注意: d1.p是一个指针。因此,它不包含任何整数,而是包含int的内存地址)。
因此,当您编写*p = 8时,您告诉程序转到p所针对的内存位置,并将该内存位置的值更改为8。(注意,这里您没有更改d1.p的内容,d1.p仍然包含相同的内存位置。相反,您只是将内存位置的内容从5更改为8)。这就是为什么当您调用d2.p时,您将得到更改后的值。因为,d2.p包含与d1.p相同的内存位置。
现在,
中释放p时,您的代码为什么会崩溃?
现在,让我先问你,你能释放已经释放的记忆吗?您可以编写代码,但行为没有定义。它可能会使你的程序崩溃,或者什么也不做。
嗯,在Dummy destructor中,你写了delete p;。现在,d2或d1将首先被销毁。让我们假设,d2被销毁了,first。所以,当d2's驱逐舰被调用时,p就是freed。然后,d1's驱逐舰将被调用,它也将尝试free p。但是p已经被释放了。在你的例子中,程序会因为这个原因而崩溃。
希望,现在一切对你来说都清楚了。
如果有什么不清楚我上面描述的,然后问问题,我会尽力回答他们。
https://stackoverflow.com/questions/63219491
复制相似问题