GURU Of THE WEEK Terms 16: General Containers with Maximum Reuse

zhaozj2021-02-08  500

GotW # 16 Maximally Reusable Generic Containers

Author: Herb Sutter

Translation: Kingofark

[Declaration]: This article takes the Guru of The Week column on www.gotw.ca website, and its copyright belongs to the original person. Translator Kingofark translated this article without the consent of the original person. This translation is only for self-study and reference, please read this article, do not reprint, spread this translation; people download this translation content, please delete its backup immediately after reading. Translator Kingofark is not responsible for people who violate the above two principles. This declaration.

Revision 1.0

GURU Of THE WEEK Terms 16: General Containers with Maximum Reuse

Difficulty: 8/10

(Can you make this simple Container Class how much adaptability (Flexibility)? Preview: In this Terms, you will learn about the knowledge of membership templates is never a little bit.)

[problem]

Copy Construction Actions and Copy Assignments are implemented for the following fixed-length VECTOR CLASS to provide maximum availability (USAbility). Tip: Consider the user code (Client Code) may use it to do those things.

Template

Class fixed_vector {

PUBLIC:

Typedef t * iterator;

Typedef const t * const_iterator;

Iterator begin () {returnv_;}

Iterator end () {returnv_ size;}

Const_iterator begin () const {returnv_;}

const_iterator end () const {return v_ size;}

Private:

T v_ [size];

}

[note]

(1) Do not modify the other parts of the code. The purpose of this Container is not to be incorporated into STL - it has at least a serious problem; gives it aim to explain some important issues in a simplified situation.

(2) The code here is based on the example originally given by Kevlin Henney. Jon Jagger has analyzed the initial example above, in the 12th and 20th of the British C User Magazine Overload column. (British readers pay attention: the solution given in this Gotw is far different from the answers in the 20th issue of British C User Magazine overload. In fact, the efficiency optimization processing plan proposed in that period will give I don't get into the gotw answer.)

[answer]

[Note: The gotw original solution here has some bugs, but it has been solved in Exceptional C and errata.

In this gotw, we changed a way: I will give the code to answer the code, and you will explain the code.

Question: How is the following solutions? Why do you work like this? Please make an instructions for each constructor and operator. Template

Class fixed_vector {

PUBLIC:

Typedef t * iterator;

Typedef const t * const_iterator;

FIXED_VECTOR () {}

Template

Fixed_vector (const fixed_vector & other) {

Copy (other.begin (),

Other.begin () min (size, iSize),

Begin ());

}

Template

Fixed_Vector &

Operator = (const fixed_vector & other) {

Copy (other.begin (),

Other.begin () min (size, iSize),

Begin ());

RETURN * THIS;

}

Iterator begin () {returnv_;}

Iterator end () {returnv_ size;}

Const_iterator begin () const {returnv_;}

const_iterator end () const {return v_ size;}

Private:

T v_ [size];

}

Now, let's analyze this code and see if it has a successful answer to the GOTW problem in this issue.

[Copy Contruction "operation and copy assignment operation]

It should first be noted that the problem of the current terms itself has suspected a red herring, the code given in the original problem itself has a good copy constructor and copy assignment. Copy Assignment Operator. Our solutions are intended to add a templated constructor and a templated assignment operator to make the constructor and assignment operation more adaptable.

I want to congratulate Valentin Bonnard and some other people, they quickly pointed out that the copy constructor is actually a copy constructor in the expected roots! In fact, even the copy assignment operator is actually a copy assignment operator!

The reason is that the true copy constructor or the copy assignment operator is only applying a fully identical type of object to constructively or assigning operations, and if it is a template class, the parameters of the template must be exactly the same. E.g:

Struct x {

Template

X (const t &); // This is not a copy constructor, because T will not be xtemplate

Operator = (const T &);

// This is not a copy assignment operator, because T will not be X

}

"But," You said, "these two templated member functions have the accurate form of copy control operation and copy assignment!" This is ... tell you: Otherwise - not this is not this, because in that two cases, t is not necessarily X. The following is taken from CD2 [Note: The same narrative also appeared in the official standard in 1998; "CD2", "COMMITTEE DRAFT 2 (Board No. 2)":

[12.8 / 2 Note 4]

Because A Template Constructor is Never a Copy Constructor, The Presence of Such A Template DOS Not Suppsels The Implicit Declaration of a Copy Construction.

Since the template constructor is not a copy constructor, the appearance of this template does not hide the statement of the original implicit copy constructor.

A similar narrative about copying assignments in [12.8 / 9 Note 7]. As a result, the code given in the answer actually has the same copy constructor as the original code in the original problem - because the compiler always generates their implicit version. What we do is only enhanced the adaptability of constructor and assignment operations, rather than replacing the old version. For example, please:

Fixed_vector v;

Fixed_vector w;

Fixed_vector w2 (w);

// Call an implicit copy constructor

Fixed_vector w3 (v);

// Call the templatened conversion constructor

W = W2; // Call an implicit assignment operator

w = v; // call template for assignment operators

It can be seen that the true answer sought by the problem of this Terfection is actually provided with adaptive "constructive and copying from other Fixed_vectors", rather than having an adaptable "copy constructor and copy value). Operation "- they have already existed.

[Application of construction operation and assignment operation]

The two operations we have increased have the following two main purposes:

1. Support variable types (including inheritance)

Although the Fixed_Vector should be kept in principle to copy and assign a value between the same type of Container, it is sometimes not meaningful from another Fixed_Vector that contains different types of objects. As long as the source object can be assigned to the destination object, the assignment between this different type of object should be allowed. For example, user code may use Fixed_Vector this:

Fixed_vector v;

Fixed_vector w (v); // copy

w = v; // assignment

Class B {/*...*/};

Class D: public b {/*...*/};

Fixed_vector x;

Fixed_vector y (x); // Copy

Y = x; // assignment

2. Supporting variable size is similar to the first point, and user code may sometimes want to construct or assign from Fixed_Vector with different sizes. It is also meaningful to support this operation. E.g:

FIXED_VECTOR v;

FIXED_VECTOR w (v); // Copy 4 objects

W = v; / / assign 4 objects

Class B {/*...*/};

Class D: public b {/*...*/};

Fixed_vector x;

Fixed_vector y (x); // Copy 16 objects

Y = x; / / assigning 16 objects

[Another solution: the standard library style answer]

I love the form of the above functions and the very good availability, but they still have something you can't do. Next, we examine a solution with a standard library style:

1. Copying

Template

FIXED_VECTOR (Iter First, Iter Last) {

COPY (First,

First Min (Size, Last-First),

Begin ());

}

So, when you want to copy, we don't have to:

FIXED_VECTOR v;

FIXED_VECTOR w (v); // Copy 4 objects

And use:

FIXED_VECTOR v;

Fixed_vector w (v.begin (), v.end ());

// Copy 4 objects

Which program is better for a construction operation? Is it a previous expected program or a standard library style program? The previous relatively easier to use some, while the latter adaptability is better (for example, it allows the user to select the operating range and copy other types of Container to copy) - You can choose any or simply two.

2. Assignment

It should be noted here that because Operator = () can only receive a parameter, we cannot let the assignment operation use the range of the Iterator as another parameter. A viable method is to provide a name function (Named function):

Template

Fixed_Vector &

Assign (iter first, iter last) {

COPY (First,

First Min (Size, Last-First),

Begin ());

RETURN * THIS;

}

So, when we want to assign a value, we don't have to:

W = v; / / assign 4 objects

And use:

W.ssign (v.begin (), v.end ());

/ / Assign 4 objects

From a technical concern, Assign () is actually not required. If we can also achieve the same degree of adaptability, but in this way, it is not very efficient when performing assignment operation, which is more unhappy:

W = Fixed_Vector (v.begin (), v.end ());

/ / Assign 4 objects

Which program is better for an assignment operation? Is it a previous expected program or this standard library style program? This time we cannot measure the use of its adaptability like this in the 1st, because the user can easily write the code for copy operation (so even more adaptive). Users will not use: w.ssign (v.begin (), v.end ());

And it will be used directly:

Copy (v.begin (), v.end (), w.begin ());

In this case, there is no need to write Assign (). So use the previously expected programs may be better, so that the user code can use COPY () directly when you need to assign an object within a range.

[Why give the default constructor? ]

Last question: Since the function of the empty default constructor in the first hypervision is the same as the default constructor generated by the compiler yourself, why is it necessary to give it in the answer code? This is because once you define an arbitrary formal constructor, the compiler will not generate its default version. Obviously, the user code like the above needs to do this.

[Summary: How is Member Function Templates? ]

I hope that the GOTW clause of this issue has made you believe that the member function template is very easy to use. In addition, I also hope that this provision allows you to understand why the member function template will be widely used in the standard library. If you are not familiar with this usage, don't be sad - not all existing compilers support member template features, but this is the rules of C standards, all compilers will soon support it. . (When writing this article, Microsoft Visual C 5.0 has been compiled by using this feature code, but in some user code routines, its compiler still cannot reasonably analyze the Osize parameters.)

Using member templates when you create your own class, you can not only please users, but also more and more, and the use of those very easy-to-use code.

(Finish)

转载请注明原文地址:https://www.9cbs.com/read-378.html

New Post(0)