使用对象进行C ++深度复制

时间:2013-01-16 17:59:44

标签: c++ deep-copy return-by-value

早上好。我无法理解在共享项目中使用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)这是一个深层还是浅层副本?

如果我遗漏了重要的一点,我道歉。我不是一个程序员,所以这样的事情很容易让我困惑。文献让我更加困惑。谢谢你的时间。

5 个答案:

答案 0 :(得分:5)

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

  2. 因为ObjectBDataMember是一个int,所以复制它不会被称为浅或深。这些概念仅用于复制指针的上下文。

  3. 例如:

    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. */
    

答案 1 :(得分:3)

“为什么数据成员的访问权限为this->ObjectBDataMember而不是this.ObjectBDataMember?”

那是因为this是一个指针,而->运算符跟随之前来的指针来访问之后的成员

“这是一个深层还是浅层副本?”

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

术语“深层复制”是指与正在复制的对象关联的所有对象的递归复制:如果数据结构S包含成员变量哪些是指针,将S(例如s1)的实例深度复制到S的另一个实例(例如,s2)意味着递归复制s1变量指向的每个对象,以便s2与这些对象的副本相关联,而不是与相同的对象相关联s1是关联的(浅层复制就是这种情况)。

在这里,你没有任何指针成员变量,所以“深”与“浅”副本的概念在这种情况下失去了意义。

答案 2 :(得分:1)

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

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

答案 3 :(得分:0)

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

之间的区别
int ObjectBDataMember;

int *ObjectBDataMember;

如果您想设置它的值,那么:

this->ObjectBDataMember = 5;

VS

*(this->ObjectBDataMember) = 5;

答案 4 :(得分:0)

  1. 因为thisObjectBType*(指针),所以要访问其成员,您需要指定->。顺便说一下,this是成员函数中的隐式变量,您可以省略它:ObjectBDataMember = objecta->DataAccessor();
  2. ObjectADataMember的类型是int,它是基本类型(不是复合),所以它只是一个副本。临时“深层复制”适用于复合类型。
  3. 我建议先完成任何好的C ++书籍,这将解决很多像这样的潜在问题