深层与浅层复制 - 第1部分 [英] Deep versus Shallow Copy - Part 1

查看:68
本文介绍了深层与浅层复制 - 第1部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经决定(请参阅前面的帖子)将我的Word文档粘贴到这里,以便它可以更简单地让人们提供反馈(通过直接插入

他们的评论在文中)。我将分三部分发布,以便更容易管理。


以下是我计划提供给我的介绍文件的草稿

C ++类。


请注意,我故意不提及安全问题

在ctors中可以解决一些组合智能

指针或异常处理。这些主题将在

后续课程中介绍。


如果有人想要MS Word中的完整文档(在我有了
$之后) b $ b包含了你们建议的改进),给我发送一封电子邮件,其中包含

Deep vs. Shallow Copy作为标题。 Word doc

的外观要好得多(这个工具在格式化时非常有限

选择,而且从
Word)。


第1部分:


主题:深层与浅层复制的说明

作者:Bob Langelaan

日期:2006年11月25日


注意:读者应该已经研究过以下C ++

概念,以便能够理解这个文档:指针和

引用; 新的和删除运营商;会员

初始化列表(MIL); 这个指针。


1.0简介


让我们从以下课程开始:


class Example1

{

private:

int ii;

double dd;

ABC abc;

};


现在让我们实例化几个Example1对象:


例1 xyz1,xyz2;

..

.. //假设xyz1'的值在这里被修改

..

xyz2 = xyz1 ; //这是允许的吗?


是的,上述程序语句在C ++中是允许的。分配

运算符通常会自动超载(请参阅下面的3.0

高级主题附录部分,以了解有关某些例外情况的详细信息)

any C ++中的类。如果程序员没有重载分配

运算符,编译器将为您执行此操作。让我们假设在这个

的情况下,程序员没有明确地重载了​​赋值

运算符。编译器提供的赋值运算符

(有时称为隐式或合成赋值

运算符)在上面的语句中做什么?


xyz1的ii成员将被分配给xyz2的ii成员; xyz1的dd

成员将被分配给xyz2的dd成员;并且xyz1的abc

成员将被分配给xyz2的abc成员。将一个对象的成员分配给

另一个对象的成员的这个过程被称为成员和成员。分配。程序员

也可以将其称为浅层副本。


如果我们有以下C ++语句怎么办?

例1 xyz3 = xyz1; //这是否也会调用重载的

//赋值运算符?


否。在这种情况下,Example1类的复制构造函数将是

被调用。就像重载赋值运算符一样,如果

程序员没有为他们的类提供拷贝构造函数,那么

编译器就会。编译器提供的复制构造函数(隐式或

合成复制构造函数)相当于在其成员初始化列表中初始化新对象成员的所有成员
(MIL)。反过来,这将导致调用每个

成员的复制构造函数。因此,在之前的C ++语句中,

编译器提供的复制构造函数将为xyz3的每个成员有效地调用复制

构造函数,并传递给每个副本

构造函数xyz1的相应成员。


但如果我们有以下类怎么办:


class Example2

{

public:

Example2();

private:

int ii;

double dd;

ABC * abcPtr; //将指向动态创建的ABC对象

};


这里是Example2构造函数的实现:


例子2 ::例子2()

{

abcPtr =新ABC; //动态创建一个ABC对象

//并让类成员abcPtr指向它。

I have decided (see earlier post) to paste my Word doc here so that it
will be simpler for people to provide feedback (by directly inserting
their comments in the post). I will post it in 3 parts to make it more
manageable.

Below is a draft of a document that I plan to give to my introductory
C++ class.

Please note that I have purposely left out any mention of safety issues
in the ctors which could be resolved thru some combination smart
pointers or exception handling. These topics will be introduced in the
follow up course.

If anyone would like the complete document in MS Word (after I have
incorporated improvements you folks suggest), send me an e-mail with
"Deep versus Shallow Copy" as a title. The appearance in the Word doc
is much better (this tool is rather limited when it comes to formatting
choices and it seems to get the indentation wrong when translating from
Word).

PART 1:

Subject: Explanation of Deep versus Shallow Copy
Author: Bob Langelaan
Date: Nov. 25th, 2006

Note: The reader should already have studied the following C++
concepts in order to be able to understand this document: pointers and
references; the "new" and "delete" operators; the member
initialization list (MIL); the "this" pointer.

1.0 Introduction

Let us start with the following class:

class Example1
{
private:
int ii;
double dd;
ABC abc;
};

Now let us instantiate several Example1 objects:

Example1 xyz1, xyz2;
..
.. // Assume xyz1''s value modified here
..
xyz2 = xyz1; // Is this allowed?

Yes, the above program statement is allowed in C++. The assignment
operator is normally automatically overloaded (see section "3.0
Advanced Topic Addendum" below for details on some exceptions) for
any class in C++. If the programmer does not overload the assignment
operator, the compiler will do it for you. Let us assume that in this
case the programmer has not explicitly overloaded the assignment
operator. What will the compiler supplied assignment operator
(sometimes called the "implicit" or "synthesized" assignment
operator) do in the statement above?

The ii member of xyz1 will be assigned to the ii member of xyz2; the dd
member of xyz1 will be assigned to the dd member of xyz2; and the abc
member of xyz1 will be assigned to the abc member of xyz2. This
process of assigning the members of one object to the members of
another object is called a "memberwise" assignment. Programmers
may also refer to this as a "shallow copy".

What if we have the following C++ statement?

Example1 xyz3 = xyz1; // Does this invoke the overloaded
// assignment operator as well?

No. In this case the copy constructor of the Example1 class will be
invoked. Just as with the overloaded assignment operator, if the
programmer does not supply a copy constructor for their class, the
compiler will. The compiler supplied copy constructor (the implicit or
synthesized copy constructor) does the equivalent to initializing all
of the members of the new object in its member initialization list
(MIL). This, in turn, will cause the copy constructor for each of the
members to be invoked. Therefore, in the previous C++ statement, the
compiler supplied copy constructor will effectively invoke the copy
constructor for each of the members of xyz3, passing to each copy
constructor the corresponding member of xyz1.

But what if we having the following class:

class Example2
{
public:
Example2();
private:
int ii;
double dd;
ABC * abcPtr; // will point to a dynamically created ABC object
};

And here is the implementation of the Example2 constructor:

Example2::Example2()
{
abcPtr = new ABC; // dynamically create an ABC object
// and have the class member abcPtr point to it.

推荐答案

2006 -11-26 19:39,blangela写道:
On 2006-11-26 19:39, blangela wrote:

如果我们有以下内容怎么办?


示例2 xyz3 = xyz1 ; //我们可以在这里使用编译器

//提供的拷贝构造函数吗?


编号。编译器提供的拷贝构造函数将执行浅拷贝。它将有效地做到这一点:


xyz3.abcPtr = xyz1.abcPtr; //这只是将一个指针

//分配给另一个指针


当我们需要它有效的时候是:

xyz3.abcPtr =新ABC; //首先动态创建一个ABC对象

//(记住xyz3是在这个拷贝构造函数中构造的)

*(xyz3.abcPtr)= *(xyz1.abcPtr) ; //然后像

//程序员提供的赋值操作符一样 - 深层复制
What if we have the following?

Example2 xyz3 = xyz1; // Can we use the compiler
// supplied copy constructor here?

No. The compiler supplied copy constructor will do a shallow copy. It
will effectively do this:

xyz3.abcPtr = xyz1.abcPtr; // this simply assigns one pointer
// to the other pointer

when what we need it to effectively do is:

xyz3.abcPtr = new ABC; // first dynamically create an ABC object
// (remember that xyz3 is constructed in this copy constructor)
*(xyz3.abcPtr) = *(xyz1.abcPtr); // then do the same as the
// programmer supplied assignment operator - a deep copy



除非你有一些教学理由不要用这样的东西不会更好




xyz3.abcPtr = new ABC(*(xyz1.abcPtr)); //复制 - 创建一个新的ABC对象


当然,既然你希望读者熟悉

初始化,那么使用它会更好初始化在

例子中:


例2:例2(例2& e)

:abcPtr(新ABS(*( e.abcPtr))

{

}


这里有点晚了所以可能有一些错误以上但是

我想你会明白的。


-

Erik Wikstr?m


Unless you have some pedagogical reason not to wouldn''t it be better
with something like this:

xyz3.abcPtr = new ABC(*(xyz1.abcPtr)); // Copy-create a new ABC object

Of course, since you expect the reader to be familiar with
initialization, it would be even better to use initialization in the
examples:

Example2::Example2(Example2& e)
: abcPtr(new ABS(*(e.abcPtr))
{
}

It''s a bit late here so there are probably some errors in the above but
I think you''ll get the idea.

--
Erik Wikstr?m




Erik Wikstr?m写道:

Erik Wikstr?m wrote:

On 2006-11-26 19:39 ,blangela写道:
On 2006-11-26 19:39, blangela wrote:

如果我们有以下内容怎么办?


示例2 xyz3 = xyz1; //我们可以使用编译器

//这里提供了复制构造函数吗?


编号。编译器提供的拷贝构造函数将执行浅拷贝。

会有效的这样做:


xyz3.abcPtr = xyz1.abcPtr; //这只是将一个指针

//分配给另一个指针


当我们需要它有效的时候是:

xyz3.abcPtr =新ABC; //首先动态创建一个ABC对象

//(记住xyz3是在这个拷贝构造函数中构造的)

*(xyz3.abcPtr)= *(xyz1.abcPtr) ; //然后像

//程序员提供的赋值操作符一样 - 深拷贝
What if we have the following?

Example2 xyz3 = xyz1; // Can we use the compiler
// supplied copy constructor here?

No. The compiler supplied copy constructor will do a shallow copy. It
will effectively do this:

xyz3.abcPtr = xyz1.abcPtr; // this simply assigns one pointer
// to the other pointer

when what we need it to effectively do is:

xyz3.abcPtr = new ABC; // first dynamically create an ABC object
// (remember that xyz3 is constructed in this copy constructor)
*(xyz3.abcPtr) = *(xyz1.abcPtr); // then do the same as the
// programmer supplied assignment operator - a deep copy




除非你有一些教学理由不是不会更好

这样的事情:


xyz3.abcPtr = new ABC(*(xyz1.abcPtr)) ; //复制 - 创建一个新的ABC对象


当然,既然你希望读者熟悉

初始化,那么使用它会更好初始化在

例子中:


例2:例2(例2& e)

:abcPtr(新ABS(*( e.abcPtr))

{

}


这里有点晚了所以可能有一些错误以上但是

我想你会明白的。


-

Erik Wikstr?m



Unless you have some pedagogical reason not to wouldn''t it be better
with something like this:

xyz3.abcPtr = new ABC(*(xyz1.abcPtr)); // Copy-create a new ABC object

Of course, since you expect the reader to be familiar with
initialization, it would be even better to use initialization in the
examples:

Example2::Example2(Example2& e)
: abcPtr(new ABS(*(e.abcPtr))
{
}

It''s a bit late here so there are probably some errors in the above but
I think you''ll get the idea.

--
Erik Wikstr?m



我的学生仍然对指针,MIL和

新操作符感到满意,所以按照我的方式进行操作会使代码更容易

明白。否则,我同意你的建议。


Bob

My students are still getting comfortable with pointers, MILs and the
new operator, so doing it the way I have shown makes the code easier to
understand. Otherwise, I agree with your suggestions.

Bob


blangela写道:
blangela wrote:

我已经决定(请参阅前面的帖子)将我的Word文档粘贴到这里,以便它可以更简单地使用它le提供反馈(通过在帖子中直接插入

他们的评论)。我将分三部分发布,以便更容易管理。


以下是我计划提供给我的介绍文件的草稿

C ++类。


请注意,我故意不提及安全问题

在ctors中可以解决一些组合智能

指针或异常处理。这些主题将在

后续课程中介绍。


如果有人想要MS Word中的完整文档(在我有了
$之后) b $ b包含了你们建议的改进),给我发送一封电子邮件,其中包含

Deep vs. Shallow Copy作为标题。 Word doc

的外观要好得多(这个工具在格式化时非常有限

选择,而且从
Word)。


第1部分:


主题:深层与浅层复制的说明

作者:Bob Langelaan

日期:2006年11月25日


注意:读者应该已经研究过以下C ++

概念,以便能够理解这个文档:指针和

引用; 新的和删除运营商;会员

初始化列表(MIL); 这个指针。


1.0简介


让我们从以下课程开始:


class Example1

{

private:

int ii;

double dd;

ABC abc;

};
I have decided (see earlier post) to paste my Word doc here so that it
will be simpler for people to provide feedback (by directly inserting
their comments in the post). I will post it in 3 parts to make it more
manageable.

Below is a draft of a document that I plan to give to my introductory
C++ class.

Please note that I have purposely left out any mention of safety issues
in the ctors which could be resolved thru some combination smart
pointers or exception handling. These topics will be introduced in the
follow up course.

If anyone would like the complete document in MS Word (after I have
incorporated improvements you folks suggest), send me an e-mail with
"Deep versus Shallow Copy" as a title. The appearance in the Word doc
is much better (this tool is rather limited when it comes to formatting
choices and it seems to get the indentation wrong when translating from
Word).

PART 1:

Subject: Explanation of Deep versus Shallow Copy
Author: Bob Langelaan
Date: Nov. 25th, 2006

Note: The reader should already have studied the following C++
concepts in order to be able to understand this document: pointers and
references; the "new" and "delete" operators; the member
initialization list (MIL); the "this" pointer.

1.0 Introduction

Let us start with the following class:

class Example1
{
private:
int ii;
double dd;
ABC abc;
};



我认为通过使用比Example1更有意义的类

来改善论文。作为例子。毕竟,如果这个例子似乎是设计的,那么学生可能会质疑材料的相关性。

所以现实越多。提供的示例,

学生越有可能将其应用于他们看到的C ++代码以及他们编写的C ++
代码。选择的具体类别并不重要:形状和形状。类,或车辆类,甚至是String

类是一些常见的选择。


另一个重要的编程课程是选择

标识符。精心挑选的名字记录了该计划,并且b $ b最大限度地减少了犯错误的可能性。出于这个原因,这个

程序没有设置一个很好的例子,因为标识符名称为

,名称最后只有一个字符。

" Example1"和实施例2 (除了没有传达任何类别实际上代表的类别)可能会建议类别名称应尽可能地与每个类别相似 - 实际上目标是相反的。 br />
因为程序员想要的最后一件事就是有两个类

,其名字很容易混淆。


Greg

I think the paper would be improved by using a more meaningful class
than "Example1" as the example. After all, if the example appears to be
contrived, then the student may question the relevancy of the material.
So the more "realistic" the example provided, the more likely that a
student will be able to apply it to C++ code they see and to the C++
code that they write. The specific class chosen does not matter all
that much: a "Shape" class, or a "Vehicle" class, or even a "String"
class are some of the usual choices.

Another important programming lesson is to choose the names of
identifiers carefully. Well-chosen names document the program and
minimize the likelihood of making a mistake. For that reason, this
program is not setting a good example by having identifiers with names
that differ only by one character at the very end of the name.
"Example1" and "Example2" (besides not communicating what either class
actually represents) may suggest that class names should resemble each
other as much as possible - when in fact the goal is the opposite.
Because the last thing that a programmer wants is to have two classes
whose names are easy to mix up.

Greg


这篇关于深层与浅层复制 - 第1部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆