The latest version of this topic can be found at Copy Constructors and Copy Assignment Operators (C++).
Starting in C++11, two kinds of assignment are supported in the language: copy assignment and move assignment. In this article "assignment" means copy assignment unless explicitly stated otherwise. For information about move assignment, see Move Constructors and Move Assignment Operators (C++).
Both the assignment operation and the initialization operation cause objects to be copied.
Assignment: When one object's value is assigned to another object, the first object is copied to the second object. Therefore,
causes the value of to be copied to .
Initialization: Initialization occurs when a new object is declared, when arguments are passed to functions by value, or when values are returned from functions by value.
You can define the semantics of "copy" for objects of class type. For example, consider this code:
The preceding code could mean "copy the contents of FILE1.DAT to FILE2.DAT" or it could mean "ignore FILE2.DAT and make a second handle to FILE1.DAT." You must attach appropriate copying semantics to each class, as follows.
By using the assignment operator together with a reference to the class type as the return type and the parameter that is passed by reference—for example .
By using the copy constructor. For more information about the copy constructor, see Rules for Declaring Constructors.
If you do not declare a copy constructor, the compiler generates a member-wise copy constructor for you. If you do not declare a copy assignment operator, the compiler generates a member-wise copy assignment operator for you. Declaring a copy constructor does not suppress the compiler-generated copy assignment operator, nor vice versa. If you implement either one, we recommend that you also implement the other one so that the meaning of the code is clear.
Member-wise assignment is covered in more detail in (NOTINBUILD) Memberwise Assignment and Initialization.
The copy constructor takes an argument of type class-name&, where class-name is the name of the class for which the constructor is defined. For example:
Make the type of the copy constructor's argument const class-name& whenever possible. This prevents the copy constructor from accidentally changing the object from which it is copying. It also enables copying from const objects.
Compiler-generated copy constructors, like user-defined copy constructors, have a single argument of type "reference to class-name." An exception is when all base classes and member classes have copy constructors declared as taking a single argument of type constclass-name&. In such a case, the compiler-generated copy constructor's argument is also const.
When the argument type to the copy constructor is not const, initialization by copying a const object generates an error. The reverse is not true: If the argument is const, you can initialize by copying an object that is not const.
Compiler-generated assignment operators follow the same pattern with regard to const. They take a single argument of type class-name& unless the assignment operators in all base and member classes take arguments of type constclass-name&. In this case, the class's generated assignment operator takes a const argument.
When virtual base classes are initialized by copy constructors, compiler-generated or user-defined, they are initialized only once: at the point when they are constructed.
The implications are similar to those of the copy constructor. When the argument type is not const, assignment from a const object generates an error. The reverse is not true: If a const value is assigned to a value that is not const, the assignment succeeds.
For more information about overloaded assignment operators, see Assignment.
Special Member Functions
The latest version of this topic can be found at C++ Stack Semantics for Reference Types.
Prior to Visual C++ 2005, an instance of a reference type could only be created using the operator, which created the object on the garbage collected heap. However, you can now create an instance of a reference type using the same syntax that you would use to create an instance of a native type on the stack. So, you do not need to use ref new, gcnew to create an object of a reference type. And when the object goes out of scope, the compiler calls the object's destructor.
When you create an instance of a reference type using stack semantics, the compiler does internally create the instance on the garbage collected heap (using ).
When the signature or return type of a function includes an instance of a by-value reference type, the function will be marked in the metadata as requiring special handling (with modreq). This special handling is currently only provided by Visual C++ clients; other languages do not currently support consuming functions or data that use reference types created with stack semantics.
One reason to use (dynamic allocation) instead of stack semantics would be if the type has no destructor. Also, using reference types created with stack semantics in function signatures would not be possible if you want your functions to be consumed by languages other than Visual C++.
The compiler will not generate a copy constructor for a reference type. Therefore, if you define a function that uses a by-value reference type in the signature, you must define a copy constructor for the reference type. A copy constructor for a reference type has a signature of the following form: .
The compiler will not generate a default assignment operator for a reference type. An assignment operator allows you to create an object using stack semantics and initialize it with an existing object created using stack semantics. An assignment operator for a reference type has a signature of the following form: .
If your type's destructor releases critical resources and you use stack semantics for reference types, you do not need to explicitly call the destructor (or call ). For more information on destructors in reference types, see Destructors and Finalizers in Visual C++.
A compiler-generated assignment operator will follow the usual standard C++ rules with the following additions:
Any non-static data members whose type is a handle to a reference type will be shallow copied (treated like a non-static data member whose type is a pointer).
Any non-static data member whose type is a value type will be shallow copied.
Any non-static data member whose type is an instance of a reference type will invoke a call to the reference type’s copy constructor.
The compiler also provides a unary operator to convert an instance of a reference type created using stack semantics to its underlying handle type.
The following reference types are not available for use with stack semantics:
The following code sample shows how to declare instances of reference types with stack semantics, how the assignment operator and copy constructor works, and how to initialize a tracking reference with reference type created using stack semantics.
Classes and Structs