Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 复制构造函数+;浅(&);深度复制_C++_Pointers_Copy Constructor_Deep Copy_Shallow Copy - Fatal编程技术网

C++ 复制构造函数+;浅(&);深度复制

C++ 复制构造函数+;浅(&);深度复制,c++,pointers,copy-constructor,deep-copy,shallow-copy,C++,Pointers,Copy Constructor,Deep Copy,Shallow Copy,我想问,当我没有显式地编写任何复制构造函数时,编译器会自动生成默认情况下执行浅复制的复制构造函数,对吗? 因此,在main()程序中,当我更改整数a、b和指针p的值时,在复制的对象中,只有p的值更改,a和b的值保持不变。为什么a&b的价值没有改变?我的代码是: #include <iostream> #include <string.h> using namespace std; class Dummy { private: int a, b;

我想问,当我没有显式地编写任何复制构造函数时,编译器会自动生成默认情况下执行浅复制的复制构造函数,对吗? 因此,在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;
}

我想说的是,当我改变对象d1的值时,对象d2的指针改变了,那么为什么对象d2的a和b的值没有改变呢

我还在析构函数中使用delete关键字删除动态分配的指针:

~Dummy() {
            delete p;
        }

但它却破坏了我的程序。这是为什么?

你完全弄错了-
浅拷贝的想法。实际上,
c++
本身并没有所谓的
deepcopy
。因此,调用某个
浅拷贝
有点错误。而仅仅是使用这些单词
浅拷贝
也会造成很多的
混淆

现在,让我解释一下,当
cpp
使用赋值执行
初始化时会发生什么
cpp
c
(在复制结构时)有一个称为
按位复制的概念。在这个概念中,
一个对象的所有成员变量(struct object/class object,你可以说是任意一个)都被相同地复制到另一个对象上
。现在,
两个对象指向同一个内存位置的想法是完全错误的。实际上,
两个对象
都有自己的
内存位置
,当然,
它们的变量
占用
不同的内存空间
。为了你,我写了一些关于记忆的测试。如果您只看到测试及其输出,就会完全理解:

#包括
#包括
使用名称空间std;
类虚拟{
INTA,b;
int*p;
公众:
伪(){
p=新整数;
}
无效集合数据(整数x,整数y,整数z){
a=x;
b=y;
*p=z;
}
void showData(){

看不见(三法则)@大修——因为你复制了它们。很明显,如果你复制了一些东西,然后改变了原来的内容,副本就不会改变。@大修——这是复制这个词的正常含义。@大修——几乎总是当初学者不理解指针时,因为他们混淆了两个不同的东西,指针的值和它所指向的东西的值nts to。这就是您正在做的。您的代码复制指针,但随后会更改指针所指向的值。这就是为什么您会看到
a
d
、和
p
@大修\uu的行为有所不同。是的,因为您的两个对象具有相同的指针值,您最终会删除相同的指针两次。这是经常发生的en会导致崩溃。为了避免这种情况,你应该遵循David C Rankin给出的关于三的规则的参考。
~Dummy() {
            delete p;
        }
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
d2.p = d1.p