C++对象深度复制

C++ deep copying with objects

本文关键字:复制 深度 对象 C++      更新时间:2023-10-16

早上好。 我无法理解共享项目中C++对象进行深度和浅层复制背后的逻辑,因此我创建了以下示例。

int main() {
    ObjectAType* objecta = ObjectAType::New();
    ObjectBType* objectb = ObjectBType::New();
    // some operation to populate data members of object a
    objecta->Operation();
    // assume I have accessors to return datamembers of object a
    // I wish to make a deep copy of SOME of those data members into object b
    objectb->AlignWithA(objecta);
    objecta->Delete();
    objectb->Delete();
    return 0;
}

现在给定对象 b 类函数如下:

public:
void ObjectBType::AlignWithA(ObjectAType* objecta) {
    this->ObjectBDataMember = objecta->DataAccessor();
}
protected:
int ObjectBDataMember;

数据访问器在类 def 中就是这样的东西,

public:
int ObjectAType::DataAccessor() {
    return this->ObjectADataMember;
}
protected:
int ObjectADataMember;

我有几个问题。

1( 由于在对象 b 中,数据成员被声明为

int ObjectBDataMember; 

而不是作为

int *ObjectBDataMember;

为什么数据成员的访问方式

this->ObjectBDataMember

而不是作为

this.ObjectBDataMember

2(这是深拷贝还是浅拷贝?

如果我遗漏了重要的部分,我深表歉意。 我不太喜欢程序员,所以这样的事情很容易让我感到困惑。 文献只是让我更加困惑。 谢谢你的时间。

  1. 在C++中,this被定义为指向当前对象的(不可修改的(指针。因此,您可以使用this->aMember来访问aMember。这与aMember具有的类型无关。(注意:只要没有使用相同名称的局部变量或函数参数,使用 this->aMember 就等效于只使用 aMember(。

  2. 因为ObjectBDataMember是一个整数,所以复制它既不称为浅层也不称为深层。这些概念仅用于复制指针的上下文。

例如:

ObjectBType* b1 = new ObjectBType();
ObjectBType* b2 = b1; // shallow copy. b1 and b2 refer to the same object.
ObjectBType* b3 = new ObjectBType(*b1); /* deep copy. b1 and b3 refer to 
  different objects that happen to have the same value. */

"为什么数据成员以this->ObjectBDataMember而不是this.ObjectBDataMember访问

?">

这是因为this是一个指针,->运算符跟随它前面的指针来访问它后面的成员。

"这是深的还是浅的?">

如果您指的是整数变量的副本,则可以将其称为浅表副本,但没有必要对其进行限定int因为它不是数据结构。

术语">深拷贝"是指与被复制对象关联的所有对象的递归复制:如果数据结构S包含作为指针的成员变量,则深拷贝S实例(例如,s1(到S的另一个实例(例如,s2(意味着递归复制由s1变量指向的每个对象,以便s2与这些对象的副本相关联, 而不是与s1关联的相同对象(浅层复制就是这种情况(。

在这里,您没有任何指针成员变量,因此"深层"与"浅层"副本的概念在此上下文中失去了意义。

  1. 当您有指针时,您可以使用->,当您有引用时,可以使用.。数据成员作为this->ObjectBDataMember进行访问this因为 是指向自身的不可修改的指针。因此,您需要->(偏移(运算符才能访问其ObjectBDataMember。应该注意的是,您不必使用自引用this指针来访问对象自己的数据成员。它只是一种用于强调代码正在访问对象自己的数据成员的样式。当您访问另一个对象的数据成员并且它们具有相同的成员(由于是相同的对象类型(时很有用。

  2. 这些对象没有分配的对象,只有普通的旧数据类型。所以它是一个浅层的副本。对象的浅表副本会复制其值,但不分配任何新对象。它仅将指针复制到任何已分配的对象。深层复制创建所有值类型成员的副本,以及创建自己的分配对象(通常复制源复制对象子对象中的值(。

this->ObjectBDataMember

深层或浅层副本无关。 this是一个指针,因此它的成员始终通过 -> 访问。 好吧,你可以做(*this).ObjectBDataMember.

两者之间的区别

int ObjectBDataMember;

int *ObjectBDataMember;

是如果你想设置它的值,你会做的:

this->ObjectBDataMember = 5;

*(this->ObjectBDataMember) = 5;
  1. 由于thisObjectBType*(指针(,因此要访问其成员,您需要指定-> 。顺便说一句,this是成员函数中的隐式变量,您可以省略它:ObjectBDataMember = objecta->DataAccessor();
  2. ObjectADataMember 的类型是 int,它是基本类型(不是复合类型(,所以它只是一个副本。 临时"深拷贝"适用于复合类型。

我建议先完成任何一本好C++书,这将解决大量像这样的潜在问题