C + + object Model--object copy Semantics (semantics) (fifth chapter)

Source: Internet
Author: User
Tags bitwise

5.3 Object Copy Semantics (object copy semantics) when designing a class, andwhen assigning a class object to a class object, there are three choices:
1. Do nothing, so the default behavior can be implemented.
2. Provide a explicit copy assignment operator.
3. Clearly deny that a class object is assigned to a class object.
Suppose you want to Select 3rd, does not agree to assign a class object to a Class object, then simply declare copy assignment operator as private and do not provide its definition to. set it to private and no longer agree to whatever location(except in member functions and friend of this class) Perform an assignment (assign) operation. Without providing its function definition, the program fails when a member function or friend attempts to affect a copyIt is generally felt that this is related to the nature of the linker.
In this section, verify the semantics of Copy assignment operator and how they are molded, using point class to help with the discussion:
Class Point {public: Point    (float x= 0.0, float y = 0.0);    // ... No virtual functionprotected:    float _x, _y;};
There is no reason to prohibit copying a point object. So the question becomes:is the default behavior sufficient? assuming that you want to support just a simple copy operation, the default behavior is not only sufficient and efficient, but does not take advantage of providing a copy assignment operator yourself.
It is only necessary to design a copy assignment operator if the semantics caused by the default behavior is unsafe or incorrect. Is the default memberwise copy behavior unsafe for point?

No, "Alias session" or "memory leak" does not occur because the coordinates are in a numeric value. Assuming that you provide copy assignment operator, the program will run slower.
Suppose an incorrect point supplies a copy assignment operator, and simply relies on the default memberwise copy, does the compiler produce an entity ?The answer is the same as copy constructor:not really! Because this class already has bitwise copy semantics, implicit copy assignment operator is considered useless, and it will not be synthesized at all.
A class for the default copy assignment operator, inThe following situation does not show bitwise copy semantics:
1. When class takes amember object While its class has a copy assignment operator.
2. When a class'swhen the base class has a copy assignment operator.
3. When a classdeclares that no matter what the virtual functions(you must not copy the Vptr address of the right-end class object, as it may be a derived class object).
4. When classinherits from a virtual base class(whether or not the base class has copy operator).
The C + + standard says that copy assignment operators does not mean that bitwise copy semantics is nontrivial. In fact, only nontrivial instances will be synthesized.
Thus, for Point class, this assignment (assign) operation:

Point A, b;a = b;
By bitwise copy, point B is copied to point a, and there is no copy assignment operator is called. This is necessary in terms of semantics or efficiency. Note that it is possible to provide a copy constructor, In order to optimize the name return value (NRV). The appearance of copy constructor should not imply that a copy assignment operator must also be provided.
Now import a copy assignment operator to illustrate the behavior of the operator under inheritance:
Inline point &point::operator= (const point &p) {    _x = p._x;    _y = p._y;}
Now you derive a Point3D class (note that virtual inheritance):
Class Point3d:virtual public Point {public:    Point3D (float x = 0.0, float y = 0.0, float z = 0.0);p rotected:    Floa t _z;};
Assuming that a copy assignment operator is not defined for Point3D, the compiler must synthesize one, and the resultant thing might look like this:
C + + pseudo code: Synthesized copy Assignment Operatorinline Point3D &point3d::operator= (Point3D *const This, const Point3D &p) {    //Call the base class function entity    this->point::operator= (p);    Memberwise copy the derived class members    _z = p._z;    return *this;}
Copy assignment operator has a non-orthogonal situation (nonorthogonal aspect, which means that the situation is not ideal, not rigorous enough), that is, it lacks a member assignment list. Therefore cannot be rewritten:
C + + pseudo code, the following nature does not support inline Point3D &point3d::operator= (const Point3D &p3d): Point (P3d), Z (p3d._z) {}
Must be written in the following two forms, the ability to call the base class copy assignment operator:
Point::operator= (P3D);
Or
(* (point *) this) = P3d;
Missing copy assignment list may seem like a trivial matter, but without it, the compiler generally has no way to suppress the previous base class copy operators being calledFor example, the following is a vertex copy operator, where Vertex is also virtual inherited from point:
Class Vertex:virtual public pointinline Vertex &vertex::operator= (const Vertex &v) {    This->point::ope Rator (v);    _next = V._next;    return *this;}
Now that Vertex3d is derived from Point3D and vertex, the following is Vertex3d's copy assignment operator:
Inline Vertex3d &vertex3d::operator= (const vertex3d &v) {    this->point::operator= (v);    This->point3d::operator (v);    This->vertex::operator= (v);}
How can the compiler suppress the copy assignment operators of point in the copy assignment operators of Point3D and vertex? The compiler can not repeat the traditional constructor solution ( Additional parameters). This is because, unlike constructor and destructor, the "Take Copy assignment operator Address" operation is legal. Therefore, the following example is the legal program code (although it also overturned the hope that the copy Assignment operator to make a more static attempt):
typedef Point3D & (Point3D::* Pmfpoint3d) (const Point3D &);p Mfpoint3d PMF = &point3d::operator=;(x.*pmf) (x) ;
//Do not understand ......... ...............
However, it is not possible to support it, but it is still necessary to insert any possible number of references to copy assignment operator, depending on its unique inheritance system. This is supported when configuring an array of class object (inside the virtual base class) , also proved to be very problematic (see section 6.2)
Another way is that the compiler might generate a differentiation function (split functions) for copy assignment operator to support this class as a most-derived class or as the middle base class. Assume that copy Assignment operator is generated by the compiler, then the "slit function solution" can be said to be defined clearly. But assuming it's done by a class designer, that's not a definition. For example, how to differentiate such functions as the following (especially when Init_ Bases () is virtual):
Inline Vertex3d &vertex3d::operator= (const vertex3d &v) {    init_bases (v);}
in fact, copy assignment operator in the case of virtual inheritance, the poor behavior, need to be particularly careful to design and explain.
Assuming you use a language-based workaround, you should provide an additional "member copy list" for copy assignment operator. Simply put, whatever solution is assumed to be based on procedural action, will result in a higher degree of complexity and a larger error propensity.
It is generally accepted that this is a weakness of language and a place where the code of the program should be carefully examined (when using virtual base classes).
there is a way to ensure that the Most-derived class will trigger the copy behavior of the virtual base class Subobject, which is the copy assignment of the derived class. At the end of the operator function entity, the operator is clearly called,Like this:
Inline Vertex3d &vertex3d::operator= (const vertex3d &v) {    this->point3d::operator= (v);    This->vertex:;operator= (v);    Must place the If your compiler dose not suppress intermediate class invocations    this->point::operator= (v) ;}
This does not omit multiple copies of the subobjects, but it ensures that the semantics are correct. There is also a workaround that requires virtual subobjects to be copied into a separate function and invoked based on call path condition.
The best way is Try not to agree to a virtual base class copy OperationThere is even a strange way to do this: do not declare data in any virtual base class

C + + object Model--object copy Semantics (semantics) (fifth chapter)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.