首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按位复制和浅拷贝有什么区别吗?

问按位复制和浅拷贝有什么区别吗?
EN

Stack Overflow用户
提问于 2020-12-27 10:56:59
回答 2查看 174关注 0票数 0

关于What is the difference between memberwise copy, bitwise copy, shallow copy and deep copy?的问题,“第一个答案”的作者说:

浅拷贝

指仅复制对象的直接成员,而不复制对象所指向的任何结构。这是当你做一些明智的复制时得到的。

为什么我们要使用2术语与、按位复制和浅拷贝相同。他们之间真的没有区别吗?

也同样适用于其他语言(不仅仅是C++),我是否可以使用这些单词一般可以互换?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-12-27 11:01:46

一个稍微明智的拷贝是一个浅拷贝,但不一定相反。

原因是,由于填充,对象中可能会有您通常忽略的部分,但它们是对象的一部分。

举个例子

代码语言:javascript
复制
struct bar {
    int x;
    foo b;
};

可以在记忆中像这样:

代码语言:javascript
复制
| x | some padding | b | more padding |

当您通过memcpy复制比特时,填充位也会被复制。通过比较成员x和b,您无法分辨两者的区别,但在位的级别上是有区别的。您可以注意到,当您比较两个对象的位明智(而不是成员)。

正如在评论中指出的那样,填充并不是浅层复制与位复制不同的唯一原因。例如

代码语言:javascript
复制
struct foo{ 
    foo* self;
    foo() : self(this) {}
    foo& operator=(const foo& other) {}
    foo(const foo& other) : self(this) {}
};

成员self应该指向对象本身,这是类的不变量(为了简单起见省略了适当的封装)。仅仅复制指针就会使self->this指向other而不是this,从而破坏不变量。operator=不需要复制任何东西,复制构造函数只需正确初始化self即可。这可以看作是一个浅拷贝,因为我们只是在“复制”指针self,而不是它所指向的指针(实际上,深拷贝在这里是致命的)。但是,按位复制会有所不同,它将在将a.self指向b后将b复制到a (这将再次破坏不变量)。

考虑一下这个例子:

代码语言:javascript
复制
#include <iostream>
#include <cstring>

struct X {
    int a = 1;
    double b = 2;
    float c = 3;
    X& operator=(const X& x){
        a = x.a;
        b = x.b;
        c = x.c;
        return *this;
    }
};

int main()
{
    X a;
    X b;
    std::cout << "sizeof(X) " << sizeof(X) << "\n";
    std::cout << "sizeof(int) " << sizeof(int) << "\n";
    std::cout << "sizeof(double) " << sizeof(double) << "\n";
    std::cout << "sizeof(float) " << sizeof(float) << "\n";
    
    //memcpy(&a,&b,sizeof(X));
    a = b;
    char* aptr = reinterpret_cast<char*>(&a);
    char* bptr = reinterpret_cast<char*>(&b);
    for (size_t i = 0; i < sizeof(X); ++i) {
        if (aptr[i] != bptr[i]) std::cout << " !!! ";
    }
}

可能的产出是:

代码语言:javascript
复制
sizeof(X) 24
sizeof(int) 4
sizeof(double) 8
sizeof(float) 4
 !!! 

X的大小不是其成员大小的总和。那是填充物。有关更多细节,请参考Struct padding in C++。

operator=做一个成员级拷贝。因为对象包含不用于成员的字节,所以在复制成员并查看位表示之后,可以观察到a和b之间的差异。

另一方面,如果复制是通过memcpy进行的,那么a和b的位表示将保证相同(即不输出!!!)。

票数 1
EN

Stack Overflow用户

发布于 2020-12-27 10:59:01

如果我正确理解,按位复制就是浅拷贝。按位复制只是在每一个位上复制以创建一个副本,而浅层副本在复制直接成员时则更为普遍,正如您在引用中所说的那样。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65465002

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档