Copy assignment operator

A copy assignment operator of class T is a non-template non-static member function with the name operator = that takes exactly one parameter of type T , T & , const T & , volatile T & , or const volatile T & . A type with a public copy assignment operator is CopyAssignable .

[ edit ] Syntax

[ edit ] explanation.

  • Typical declaration of a copy assignment operator when copy-and-swap idiom can be used
  • Typical declaration of a copy assignment operator when copy-and-swap idiom cannot be used
  • Forcing a copy assignment operator to be generated by the compiler
  • Avoiding implicit copy assignment

The copy assignment operator is called whenever selected by overload resolution , e.g. when an object appears on the left side of an assignment expression.

[ edit ] Implicitly-declared copy assignment operator

If no user-defined copy assignment operators are provided for a class type ( struct , class , or union ), the compiler will always declare one as an inline public member of the class. This implicitly-declared copy assignment operator has the form T & T :: operator = ( const T & ) if all of the following is true:

  • each direct base B of T has a copy assignment operator whose parameters are B or const B& or const volatile B &
  • each non-static data member M of T of class type or array of class type has a copy assignment operator whose parameters are M or const M& or const volatile M &

Otherwise the implicitly-declared copy assignment operator is declared as T & T :: operator = ( T & ) . (Note that due to these rules, the implicitly-declared copy assignment operator cannot bind to a volatile lvalue argument)

A class can have multiple copy assignment operators, e.g. both T & T :: operator = ( const T & ) and T & T :: operator = ( T ) . If some user-defined copy assignment operators are present, the user may still force the generation of the implicitly declared copy assignment operator with the keyword default .

Because the copy assignment operator is always declared for any class, the base class assignment operator is always hidden. If a using-declaration is used to bring in the assignment operator from the base class, and its argument type could be the same as the argument type of the implicit assignment operator of the derived class, the using-declaration is also hidden by the implicit declaration.

[ edit ] Deleted implicitly-declared copy assignment operator

The implicitly-declared or defaulted copy assignment operator for class T is defined as deleted in any of the following is true:

  • T has a non-static data member that is const
  • T has a non-static data member of a reference type.
  • T has a non-static data member that cannot be copy-assigned (has deleted, inaccessible, or ambiguous copy assignment operator)
  • T has direct or virtual base class that cannot be copy-assigned (has deleted, inaccessible, or ambiguous move assignment operator)
  • T has a user-declared move constructor
  • T has a user-declared move assignment operator

[ edit ] Trivial copy assignment operator

The implicitly-declared copy assignment operator for class T is trivial if all of the following is true:

  • T has no virtual member functions
  • T has no virtual base classes
  • The copy assignment operator selected for every direct base of T is trivial
  • The copy assignment operator selected for every non-static class type (or array of class type) memeber of T is trivial

A trivial copy assignment operator makes a copy of the object representation as if by std:: memmove . All data types compatible with the C language (POD types) are trivially copy-assignable.

[ edit ] Implicitly-defined copy assignment operator

If the implicitly-declared copy assignment operator is not deleted or trivial, it is defined (that is, a function body is generated and compiled) by the compiler. For union types, the implicitly-defined copy assignment copies the object representation (as by std:: memmove ). For non-union class types ( class and struct ), the operator performs member-wise copy assignment of the object's bases and non-static members, in their initialization order, using, using built-in assignment for the scalars and copy assignment operator for class types.

The generation of the implicitly-defined copy assignment operator is deprecated (since C++11) if T has a user-declared destructor or user-declared copy constructor.

[ edit ] Notes

If both copy and move assignment operators are provided, overload resolution selects the move assignment if the argument is an rvalue (either prvalue such as a nameless temporary or xvalue such as the result of std:: move ), and selects the copy assignment if the argument is lvalue (named object or a function/operator returning lvalue reference). If only the copy assignment is provided, all argument categories select it (as long as it takes its argument by value or as reference to const, since rvalues can bind to const references), which makes copy assignment the fallback for move assignment, when move is unavailable.

[ edit ] Copy and swap

Copy assignment operator can be expressed in terms of copy constructor, destructor, and the swap() member function, if one is provided:

T & T :: operator = ( T arg ) { // copy/move constructor is called to construct arg     swap ( arg ) ;     // resources exchanged between *this and arg     return * this ; }   // destructor is called to release the resources formerly held by *this

For non-throwing swap(), this form provides strong exception guarantee . For rvalue arguments, this form automatically invokes the move constructor, and is sometimes referred to as "unifying assignment operator" (as in, both copy and move).

[ edit ] Example

This browser is no longer supported.

Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.

Copy constructors and copy assignment operators (C++)

  • 8 contributors

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. So, this code copies the value of b into a :

Initialization : Initialization occurs when you declare a new object, when you pass function arguments by value, or when you return by value from a function.

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 b a second handle to FILE1.DAT." You must attach appropriate copying semantics to each class, as follows:

Use an assignment operator operator= that returns a reference to the class type and takes one parameter that's passed by const reference—for example ClassName& operator=(const ClassName& x); .

Use the copy constructor.

If you don't declare a copy constructor, the compiler generates a member-wise copy constructor for you. Similarly, if you don't declare a copy assignment operator, the compiler generates a member-wise copy assignment operator for you. Declaring a copy constructor doesn't suppress the compiler-generated copy assignment operator, and vice-versa. If you implement either one, we recommend that you implement the other one, too. When you implement both, the meaning of the code is clear.

The copy constructor takes an argument of type ClassName& , where ClassName is the name of the class. For example:

Make the type of the copy constructor's argument const ClassName& whenever possible. This prevents the copy constructor from accidentally changing the copied object. It also lets you copy from const objects.

Compiler generated copy constructors

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 const class-name & . In such a case, the compiler-generated copy constructor's argument is also const .

When the argument type to the copy constructor isn't const , initialization by copying a const object generates an error. The reverse isn't true: If the argument is const , you can initialize by copying an object that's not const .

Compiler-generated assignment operators follow the same pattern for const . They take a single argument of type ClassName& unless the assignment operators in all base and member classes take arguments of type const ClassName& . In this case, the generated assignment operator for the class takes a const argument.

When virtual base classes are initialized by copy constructors, whether compiler-generated or user-defined, they're initialized only once: at the point when they are constructed.

The implications are similar to the copy constructor. When the argument type isn't const , assignment from a const object generates an error. The reverse isn't true: If a const value is assigned to a value that's not const , the assignment succeeds.

For more information about overloaded assignment operators, see Assignment .

Was this page helpful?

Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see: https://aka.ms/ContentUserFeedback .

Submit and view feedback for

Additional resources

Copy assignment operator

A copy assignment operator of class T is a non-template non-static member function with the name operator = that takes exactly one parameter of type T , T & , const T & , volatile T & , or const volatile T & . For a type to be CopyAssignable , it must have a public copy assignment operator.

Explanation

  • Typical declaration of a copy assignment operator when copy-and-swap idiom can be used.
  • Typical declaration of a copy assignment operator when copy-and-swap idiom cannot be used (non-swappable type or degraded performance).
  • Forcing a copy assignment operator to be generated by the compiler.
  • Avoiding implicit copy assignment.

The copy assignment operator is called whenever selected by overload resolution , e.g. when an object appears on the left side of an assignment expression.

Implicitly-declared copy assignment operator

If no user-defined copy assignment operators are provided for a class type ( struct , class , or union ), the compiler will always declare one as an inline public member of the class. This implicitly-declared copy assignment operator has the form T & T :: operator = ( const T & ) if all of the following is true:

  • each direct base B of T has a copy assignment operator whose parameters are B or const B & or const volatile B & ;
  • each non-static data member M of T of class type or array of class type has a copy assignment operator whose parameters are M or const M & or const volatile M & .

Otherwise the implicitly-declared copy assignment operator is declared as T & T :: operator = ( T & ) . (Note that due to these rules, the implicitly-declared copy assignment operator cannot bind to a volatile lvalue argument.)

A class can have multiple copy assignment operators, e.g. both T & T :: operator = ( const T & ) and T & T :: operator = ( T ) . If some user-defined copy assignment operators are present, the user may still force the generation of the implicitly declared copy assignment operator with the keyword default . (since C++11)

The implicitly-declared (or defaulted on its first declaration) copy assignment operator has an exception specification as described in dynamic exception specification (until C++17) exception specification (since C++17)

Because the copy assignment operator is always declared for any class, the base class assignment operator is always hidden. If a using-declaration is used to bring in the assignment operator from the base class, and its argument type could be the same as the argument type of the implicit assignment operator of the derived class, the using-declaration is also hidden by the implicit declaration.

Deleted implicitly-declared copy assignment operator

A implicitly-declared copy assignment operator for class T is defined as deleted if any of the following is true:

  • T has a user-declared move constructor;
  • T has a user-declared move assignment operator.

Otherwise, it is defined as defaulted.

A defaulted copy assignment operator for class T is defined as deleted if any of the following is true:

  • T has a non-static data member of non-class type (or array thereof) that is const ;
  • T has a non-static data member of a reference type;
  • T has a non-static data member or a direct or virtual base class that cannot be copy-assigned (overload resolution for the copy assignment fails, or selects a deleted or inaccessible function);
  • T is a union-like class , and has a variant member whose corresponding assignment operator is non-trivial.

Trivial copy assignment operator

The copy assignment operator for class T is trivial if all of the following is true:

  • it is not user-provided (meaning, it is implicitly-defined or defaulted) , , and if it is defaulted, its signature is the same as implicitly-defined (until C++14) ;
  • T has no virtual member functions;
  • T has no virtual base classes;
  • the copy assignment operator selected for every direct base of T is trivial;
  • the copy assignment operator selected for every non-static class type (or array of class type) member of T is trivial;

A trivial copy assignment operator makes a copy of the object representation as if by std::memmove . All data types compatible with the C language (POD types) are trivially copy-assignable.

Implicitly-defined copy assignment operator

If the implicitly-declared copy assignment operator is neither deleted nor trivial, it is defined (that is, a function body is generated and compiled) by the compiler if odr-used . For union types, the implicitly-defined copy assignment copies the object representation (as by std::memmove ). For non-union class types ( class and struct ), the operator performs member-wise copy assignment of the object's bases and non-static members, in their initialization order, using built-in assignment for the scalars and copy assignment operator for class types.

The generation of the implicitly-defined copy assignment operator is deprecated (since C++11) if T has a user-declared destructor or user-declared copy constructor.

If both copy and move assignment operators are provided, overload resolution selects the move assignment if the argument is an rvalue (either a prvalue such as a nameless temporary or an xvalue such as the result of std::move ), and selects the copy assignment if the argument is an lvalue (named object or a function/operator returning lvalue reference). If only the copy assignment is provided, all argument categories select it (as long as it takes its argument by value or as reference to const, since rvalues can bind to const references), which makes copy assignment the fallback for move assignment, when move is unavailable.

It is unspecified whether virtual base class subobjects that are accessible through more than one path in the inheritance lattice, are assigned more than once by the implicitly-defined copy assignment operator (same applies to move assignment ).

See assignment operator overloading for additional detail on the expected behavior of a user-defined copy-assignment operator.

Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

cppreference.com

Search

Copy assignment operator

A copy assignment operator of class T is a non-template non-static member function with the name operator = that takes exactly one parameter of type T , T & , const T & , volatile T & , or const volatile T & . For a type to be CopyAssignable , it must have a public copy assignment operator.

[ edit ] Syntax

[ edit ] explanation.

  • Typical declaration of a copy assignment operator when copy-and-swap idiom can be used
  • Typical declaration of a copy assignment operator when copy-and-swap idiom cannot be used (non-swappable type or degraded performance)
  • Forcing a copy assignment operator to be generated by the compiler
  • Avoiding implicit copy assignment

The copy assignment operator is called whenever selected by overload resolution , e.g. when an object appears on the left side of an assignment expression.

[ edit ] Implicitly-declared copy assignment operator

If no user-defined copy assignment operators are provided for a class type ( struct , class , or union ), the compiler will always declare one as an inline public member of the class. This implicitly-declared copy assignment operator has the form T & T :: operator = ( const T & ) if all of the following is true:

  • each direct base B of T has a copy assignment operator whose parameters are B or const B& or const volatile B &
  • each non-static data member M of T of class type or array of class type has a copy assignment operator whose parameters are M or const M& or const volatile M &

Otherwise the implicitly-declared copy assignment operator is declared as T & T :: operator = ( T & ) . (Note that due to these rules, the implicitly-declared copy assignment operator cannot bind to a volatile lvalue argument)

A class can have multiple copy assignment operators, e.g. both T & T :: operator = ( const T & ) and T & T :: operator = ( T ) . If some user-defined copy assignment operators are present, the user may still force the generation of the implicitly declared copy assignment operator with the keyword default . (since C++11)

Because the copy assignment operator is always declared for any class, the base class assignment operator is always hidden. If a using-declaration is used to bring in the assignment operator from the base class, and its argument type could be the same as the argument type of the implicit assignment operator of the derived class, the using-declaration is also hidden by the implicit declaration.

[ edit ] Deleted implicitly-declared copy assignment operator

A implicitly-declared copy assignment operator for class T is defined as deleted if any of the following is true:

  • T has a user-declared move constructor
  • T has a user-declared move assignment operator

Otherwise, it is defined as defaulted.

A defaulted copy assignment operator for class T is defined as deleted if any of the following is true:

  • T has a non-static data member of non-class type (or array thereof) that is const
  • T has a non-static data member of a reference type.
  • T has a non-static data member or a direct or virtual base class that cannot be copy-assigned (overload resolution for the copy assignment fails, or selects a deleted or inaccessible function)
  • T is a union-like class , and has a variant member whose corresponding assignment operator is non-trivial.

[ edit ] Trivial copy assignment operator

The copy assignment operator for class T is trivial if all of the following is true:

  • It is not user-provided (meaning, it is implicitly-defined or defaulted), and if it is defaulted, its signature is the same as implicitly-defined
  • T has no virtual member functions
  • T has no virtual base classes
  • The copy assignment operator selected for every direct base of T is trivial
  • The copy assignment operator selected for every non-static class type (or array of class type) member of T is trivial

A trivial copy assignment operator makes a copy of the object representation as if by std::memmove . All data types compatible with the C language (POD types) are trivially copy-assignable.

[ edit ] Implicitly-defined copy assignment operator

If the implicitly-declared copy assignment operator is neither deleted nor trivial, it is defined (that is, a function body is generated and compiled) by the compiler if odr-used . For union types, the implicitly-defined copy assignment copies the object representation (as by std::memmove ). For non-union class types ( class and struct ), the operator performs member-wise copy assignment of the object's bases and non-static members, in their initialization order, using built-in assignment for the scalars and copy assignment operator for class types.

The generation of the implicitly-defined copy assignment operator is deprecated (since C++11) if T has a user-declared destructor or user-declared copy constructor.

[ edit ] Notes

If both copy and move assignment operators are provided, overload resolution selects the move assignment if the argument is an rvalue (either prvalue such as a nameless temporary or xvalue such as the result of std::move ), and selects the copy assignment if the argument is lvalue (named object or a function/operator returning lvalue reference). If only the copy assignment is provided, all argument categories select it (as long as it takes its argument by value or as reference to const, since rvalues can bind to const references), which makes copy assignment the fallback for move assignment, when move is unavailable.

It is unspecified whether virtual base class subobjects that are accessible through more than one path in the inheritance lattice, are assigned more than once by the implicitly-defined copy assignment operator (same applies to move assignment ).

[ edit ] Copy and swap

Copy assignment operator can be expressed in terms of copy constructor, destructor, and the swap() member function, if one is provided:

T & T :: operator = ( T arg ) { // copy/move constructor is called to construct arg     swap ( arg ) ;     // resources exchanged between *this and arg     return * this ; }   // destructor is called to release the resources formerly held by *this

For non-throwing swap(), this form provides strong exception guarantee . For rvalue arguments, this form automatically invokes the move constructor, and is sometimes referred to as "unifying assignment operator" (as in, both copy and move). However, this approach is not always advisable due to potentially significant overhead: see assignment operator overloading for details.

[ edit ] Example

  • Recent changes
  • Offline version
  • What links here
  • Related changes
  • Upload file
  • Special pages
  • Printable version
  • Permanent link
  • Page information
  • In other languages
  • This page was last modified on 30 November 2015, at 07:24.
  • This page has been accessed 110,155 times.
  • Privacy policy
  • About cppreference.com
  • Disclaimers

Powered by MediaWiki

Copy assignment operator

A copy assignment operator of class T is a non-template non-static member function with the name operator= that takes exactly one parameter (that isn't an explicit object parameter ) of type T , T& , const T& , volatile T& , or const volatile T& . For a type to be CopyAssignable , it must have a public copy assignment operator.

Explanation

The copy assignment operator is called whenever selected by overload resolution , e.g. when an object appears on the left side of an assignment expression.

Implicitly-declared copy assignment operator

If no user-defined copy assignment operators are provided for a class type ( struct , class , or union ), the compiler will always declare one as an inline public member of the class. This implicitly-declared copy assignment operator has the form T& T::operator=(const T&) if all of the following is true:

  • each direct base B of T has a copy assignment operator whose parameters are B or const B& or const volatile B& ;
  • each non-static data member M of T of class type or array of class type has a copy assignment operator whose parameters are M or const M& or const volatile M& .

Otherwise the implicitly-declared copy assignment operator is declared as T& T::operator=(T&) . (Note that due to these rules, the implicitly-declared copy assignment operator cannot bind to a volatile lvalue argument.).

A class can have multiple copy assignment operators, e.g. both T& T::operator=(T&) and T& T::operator=(T) . If some user-defined copy assignment operators are present, the user may still force the generation of the implicitly declared copy assignment operator with the keyword default . (since C++11) .

The implicitly-declared (or defaulted on its first declaration) copy assignment operator has an exception specification as described in dynamic exception specification (until C++17) noexcept specification (since C++17) .

Because the copy assignment operator is always declared for any class, the base class assignment operator is always hidden. If a using-declaration is used to bring in the assignment operator from the base class, and its argument type could be the same as the argument type of the implicit assignment operator of the derived class, the using-declaration is also hidden by the implicit declaration.

Deleted implicitly-declared copy assignment operator

An implicitly-declared copy assignment operator for class T is defined as deleted if any of the following is true:

  • T has a user-declared move constructor;
  • T has a user-declared move assignment operator.

Otherwise, it is defined as defaulted.

A defaulted copy assignment operator for class T is defined as deleted if any of the following is true:

  • T has a non-static data member of a const-qualified non-class type (or array thereof);
  • T has a non-static data member of a reference type;
  • T has a non-static data member or a direct base class that cannot be copy-assigned (overload resolution for the copy assignment fails, or selects a deleted or inaccessible function);
  • T is a union-like class , and has a variant member whose corresponding assignment operator is non-trivial.

Trivial copy assignment operator

The copy assignment operator for class T is trivial if all of the following is true:

  • it is not user-provided (meaning, it is implicitly-defined or defaulted);
  • T has no virtual member functions;
  • T has no virtual base classes;
  • the copy assignment operator selected for every direct base of T is trivial;
  • the copy assignment operator selected for every non-static class type (or array of class type) member of T is trivial.

A trivial copy assignment operator makes a copy of the object representation as if by std::memmove . All data types compatible with the C language (POD types) are trivially copy-assignable.

Eligible copy assignment operator

Triviality of eligible copy assignment operators determines whether the class is a trivially copyable type .

Implicitly-defined copy assignment operator

If the implicitly-declared copy assignment operator is neither deleted nor trivial, it is defined (that is, a function body is generated and compiled) by the compiler if odr-used or needed for constant evaluation (since C++14) . For union types, the implicitly-defined copy assignment copies the object representation (as by std::memmove ). For non-union class types ( class and struct ), the operator performs member-wise copy assignment of the object's bases and non-static members, in their initialization order, using built-in assignment for the scalars and copy assignment operator for class types.

If both copy and move assignment operators are provided, overload resolution selects the move assignment if the argument is an rvalue (either a prvalue such as a nameless temporary or an xvalue such as the result of std::move ), and selects the copy assignment if the argument is an lvalue (named object or a function/operator returning lvalue reference). If only the copy assignment is provided, all argument categories select it (as long as it takes its argument by value or as reference to const, since rvalues can bind to const references), which makes copy assignment the fallback for move assignment, when move is unavailable.

It is unspecified whether virtual base class subobjects that are accessible through more than one path in the inheritance lattice, are assigned more than once by the implicitly-defined copy assignment operator (same applies to move assignment ).

See assignment operator overloading for additional detail on the expected behavior of a user-defined copy-assignment operator.

Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

  • converting constructor
  • copy constructor
  • copy elision
  • default constructor
  • aggregate initialization
  • constant initialization
  • copy initialization
  • default initialization
  • direct initialization
  • initializer list
  • list initialization
  • reference initialization
  • value initialization
  • zero initialization
  • move assignment
  • move constructor

© cppreference.com Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0. https://en.cppreference.com/w/cpp/language/as_operator

  • Graphics and multimedia
  • Language Features
  • Unix/Linux programming
  • Source Code
  • Standard Library
  • Tips and Tricks
  • Tools and Libraries
  • Windows API
  • Copy constructors, assignment operators,

Copy constructors, assignment operators, and exception safe assignment

*

Learn C++

22.3 — Move constructors and move assignment

In lesson 22.1 -- Introduction to smart pointers and move semantics , we took a look at std::auto_ptr, discussed the desire for move semantics, and took a look at some of the downsides that occur when functions designed for copy semantics (copy constructors and copy assignment operators) are redefined to implement move semantics.

In this lesson, we’ll take a deeper look at how C++11 resolves these problems via move constructors and move assignment.

Recapping copy constructors and copy assignment

First, let’s take a moment to recap copy semantics.

Copy constructors are used to initialize a class by making a copy of an object of the same class. Copy assignment is used to copy one class object to another existing class object. By default, C++ will provide a copy constructor and copy assignment operator if one is not explicitly provided. These compiler-provided functions do shallow copies, which may cause problems for classes that allocate dynamic memory. So classes that deal with dynamic memory should override these functions to do deep copies.

Returning back to our Auto_ptr smart pointer class example from the first lesson in this chapter, let’s look at a version that implements a copy constructor and copy assignment operator that do deep copies, and a sample program that exercises them:

In this program, we’re using a function named generateResource() to create a smart pointer encapsulated resource, which is then passed back to function main(). Function main() then assigns that to an existing Auto_ptr3 object.

When this program is run, it prints:

(Note: You may only get 4 outputs if your compiler elides the return value from function generateResource())

That’s a lot of resource creation and destruction going on for such a simple program! What’s going on here?

Let’s take a closer look. There are 6 key steps that happen in this program (one for each printed message):

  • Inside generateResource(), local variable res is created and initialized with a dynamically allocated Resource, which causes the first “Resource acquired”.
  • Res is returned back to main() by value. We return by value here because res is a local variable -- it can’t be returned by address or reference because res will be destroyed when generateResource() ends. So res is copy constructed into a temporary object. Since our copy constructor does a deep copy, a new Resource is allocated here, which causes the second “Resource acquired”.
  • Res goes out of scope, destroying the originally created Resource, which causes the first “Resource destroyed”.
  • The temporary object is assigned to mainres by copy assignment. Since our copy assignment also does a deep copy, a new Resource is allocated, causing yet another “Resource acquired”.
  • The assignment expression ends, and the temporary object goes out of expression scope and is destroyed, causing a “Resource destroyed”.
  • At the end of main(), mainres goes out of scope, and our final “Resource destroyed” is displayed.

So, in short, because we call the copy constructor once to copy construct res to a temporary, and copy assignment once to copy the temporary into mainres, we end up allocating and destroying 3 separate objects in total.

Inefficient, but at least it doesn’t crash!

However, with move semantics, we can do better.

Move constructors and move assignment

C++11 defines two new functions in service of move semantics: a move constructor, and a move assignment operator. Whereas the goal of the copy constructor and copy assignment is to make a copy of one object to another, the goal of the move constructor and move assignment is to move ownership of the resources from one object to another (which is typically much less expensive than making a copy).

Defining a move constructor and move assignment work analogously to their copy counterparts. However, whereas the copy flavors of these functions take a const l-value reference parameter (which will bind to just about anything), the move flavors of these functions use non-const rvalue reference parameters (which only bind to rvalues).

Here’s the same Auto_ptr3 class as above, with a move constructor and move assignment operator added. We’ve left in the deep-copying copy constructor and copy assignment operator for comparison purposes.

The move constructor and move assignment operator are simple. Instead of deep copying the source object (a) into the implicit object, we simply move (steal) the source object’s resources. This involves shallow copying the source pointer into the implicit object, then setting the source pointer to null.

When run, this program prints:

That’s much better!

The flow of the program is exactly the same as before. However, instead of calling the copy constructor and copy assignment operators, this program calls the move constructor and move assignment operators. Looking a little more deeply:

  • Res is returned back to main() by value. Res is move constructed into a temporary object, transferring the dynamically created object stored in res to the temporary object. We’ll talk about why this happens below.
  • Res goes out of scope. Because res no longer manages a pointer (it was moved to the temporary), nothing interesting happens here.
  • The temporary object is move assigned to mainres. This transfers the dynamically created object stored in the temporary to mainres.
  • The assignment expression ends, and the temporary object goes out of expression scope and is destroyed. However, because the temporary no longer manages a pointer (it was moved to mainres), nothing interesting happens here either.

So instead of copying our Resource twice (once for the copy constructor and once for the copy assignment), we transfer it twice. This is more efficient, as Resource is only constructed and destroyed once instead of three times.

Related content

Move constructors and move assignment should be marked as noexcept . This tells the compiler that these functions will not throw exceptions.

We introduce noexcept in lesson 27.9 -- Exception specifications and noexcept and discuss why move constructors and move assignment are marked as noexcept in lesson 27.10 -- std::move_if_noexcept .

When are the move constructor and move assignment called?

The move constructor and move assignment are called when those functions have been defined, and the argument for construction or assignment is an rvalue. Most typically, this rvalue will be a literal or temporary value.

The copy constructor and copy assignment are used otherwise (when the argument is an lvalue, or when the argument is an rvalue and the move constructor or move assignment functions aren’t defined).

Implicit move constructor and move assignment operator

The compiler will create an implicit move constructor and move assignment operator if all of the following are true:

  • There are no user-declared copy constructors or copy assignment operators.
  • There are no user-declared move constructors or move assignment operators.
  • There is no user-declared destructor.

The implicit move constructor and implicit move assignment operator both do a memberwise move. That is, each member of the moved-from object is moved to the moved-to object.

The key insight behind move semantics

You now have enough context to understand the key insight behind move semantics.

If we construct an object or do an assignment where the argument is an l-value, the only thing we can reasonably do is copy the l-value. We can’t assume it’s safe to alter the l-value, because it may be used again later in the program. If we have an expression “a = b” (where b is an lvalue), we wouldn’t reasonably expect b to be changed in any way.

However, if we construct an object or do an assignment where the argument is an r-value, then we know that r-value is just a temporary object of some kind. Instead of copying it (which can be expensive), we can simply transfer its resources (which is cheap) to the object we’re constructing or assigning. This is safe to do because the temporary will be destroyed at the end of the expression anyway, so we know it will never be used again!

C++11, through r-value references, gives us the ability to provide different behaviors when the argument is an r-value vs an l-value, enabling us to make smarter and more efficient decisions about how our objects should behave.

Key insight

Move semantics is an optimization opportunity.

Move functions should always leave both objects in a valid state

In the above examples, both the move constructor and move assignment functions set a.m_ptr to nullptr. This may seem extraneous -- after all, if a is a temporary r-value, why bother doing “cleanup” if parameter a is going to be destroyed anyway?

The answer is simple: When a goes out of scope, the destructor for a will be called, and a.m_ptr will be deleted. If at that point, a.m_ptr is still pointing to the same object as m_ptr , then m_ptr will be left as a dangling pointer. When the object containing m_ptr eventually gets used (or destroyed), we’ll get undefined behavior.

When implementing move semantics, it is important to ensure the moved-from object is left in a valid state, so that it will destruct properly (without creating undefined behavior).

Automatic l-values returned by value may be moved instead of copied

In the generateResource() function of the Auto_ptr4 example above, when variable res is returned by value, it is moved instead of copied, even though res is an l-value. The C++ specification has a special rule that says automatic objects returned from a function by value can be moved even if they are l-values. This makes sense, since res was going to be destroyed at the end of the function anyway! We might as well steal its resources instead of making an expensive and unnecessary copy.

Although the compiler can move l-value return values, in some cases it may be able to do even better by simply eliding the copy altogether (which avoids the need to make a copy or do a move at all). In such a case, neither the copy constructor nor move constructor would be called.

Disabling copying

In the Auto_ptr4 class above, we left in the copy constructor and assignment operator for comparison purposes. But in move-enabled classes, it is sometimes desirable to delete the copy constructor and copy assignment functions to ensure copies aren’t made. In the case of our Auto_ptr class, we don’t want to copy our templated object T -- both because it’s expensive, and whatever class T is may not even support copying!

Here’s a version of Auto_ptr that supports move semantics but not copy semantics:

If you were to try to pass an Auto_ptr5 l-value to a function by value, the compiler would complain that the copy constructor required to initialize the function parameter has been deleted. This is good, because we should probably be passing Auto_ptr5 by const l-value reference anyway!

Auto_ptr5 is (finally) a good smart pointer class. And, in fact the standard library contains a class very much like this one (that you should use instead), named std::unique_ptr. We’ll talk more about std::unique_ptr later in this chapter.

Another example

Let’s take a look at another class that uses dynamic memory: a simple dynamic templated array. This class contains a deep-copying copy constructor and copy assignment operator.

Now let’s use this class in a program. To show you how this class performs when we allocate a million integers on the heap, we’re going to leverage the Timer class we developed in lesson 18.4 -- Timing your code . We’ll use the Timer class to time how fast our code runs, and show you the performance difference between copying and moving.

On one of the author’s machines, in release mode, this program executed in 0.00825559 seconds.

Now let’s run the same program again, replacing the copy constructor and copy assignment with a move constructor and move assignment.

On the same machine, this program executed in 0.0056 seconds.

Comparing the runtime of the two programs, (0.00825559 - 0.0056) / 0.00825559 * 100 = 32.1% faster!

Do not implement move semantics using std::swap

Since the goal of move semantics is to move a resource from a source object to a destination object, you might think about implementing the move constructor and move assignment operator using std::swap() . However, this is a bad idea, as std::swap() calls both the move constructor and move assignment on move-capable objects, which would result in an infinite recursion. You can see this happen in the following example:

This prints:

And so on… until the stack overflows.

You can implement the move constructor and move assignment using your own swap function, as long as your swap member function does not call the move constructor or move assignment. Here’s an example of how that can be done:

This works as expected, and prints:

Deleting the move constructor and move assignment

You can delete the move constructor and move assignment using the = delete syntax in the exact same way you can delete the copy constructor and copy assignment.

If you delete the copy constructor, the compiler will not generate an implicit move constructor (making your objects neither copyable nor movable). Therefore, when deleting the copy constructor, it is useful to be explicit about what behavior you want from your move constructors. Either explicitly delete them (making it clear this is the desired behavior), or default them (making the class move-only).

The rule of five says that if the copy constructor, copy assignment, move constructor, move assignment, or destructor are defined or deleted, then each of those functions should be defined or deleted.

While deleting only the move constructor and move assignment may seem like a good idea if you want a copyable but not movable object, this has the unfortunate consequence of making the class not returnable by value in cases where mandatory copy elision does not apply. This happens because a deleted move constructor is still declared, and thus is eligible for overload resolution. And return by value will favor a deleted move constructor over a non-deleted copy constructor. This is illustrated by the following program:

guest

  • Python Basics
  • Interview Questions
  • Python Quiz
  • Popular Packages
  • Python Projects
  • Practice Python
  • AI With Python
  • Learn Python3
  • Python Automation
  • Python Web Dev
  • DSA with Python
  • Python OOPs
  • Dictionaries

Python Operators

Precedence and associativity of operators in python.

  • Python Arithmetic Operators
  • Difference between / vs. // operator in Python
  • Python - Star or Asterisk operator ( * )
  • What does the Double Star operator mean in Python?
  • Division Operators in Python
  • Modulo operator (%) in Python
  • Python Logical Operators
  • Python OR Operator
  • Difference between 'and' and '&' in Python
  • not Operator in Python | Boolean Logic

Ternary Operator in Python

  • Python Bitwise Operators

Python Assignment Operators

Assignment operators in python.

  • Walrus Operator in Python 3.8
  • Increment += and Decrement -= Assignment Operators in Python
  • Merging and Updating Dictionary Operators in Python 3.9
  • New '=' Operator in Python3.8 f-string

Python Relational Operators

  • Comparison Operators in Python
  • Python NOT EQUAL operator
  • Difference between == and is operator in Python
  • Chaining comparison operators in Python
  • Python Membership and Identity Operators
  • Difference between != and is not operator in Python

In Python programming, Operators in general are used to perform operations on values and variables. These are standard symbols used for logical and arithmetic operations. In this article, we will look into different types of Python operators. 

  • OPERATORS: These are the special symbols. Eg- + , * , /, etc.
  • OPERAND: It is the value on which the operator is applied.

Types of Operators in Python

  • Arithmetic Operators
  • Comparison Operators
  • Logical Operators
  • Bitwise Operators
  • Assignment Operators
  • Identity Operators and Membership Operators

Python Operators

Arithmetic Operators in Python

Python Arithmetic operators are used to perform basic mathematical operations like addition, subtraction, multiplication , and division .

In Python 3.x the result of division is a floating-point while in Python 2.x division of 2 integers was an integer. To obtain an integer result in Python 3.x floored (// integer) is used.

Example of Arithmetic Operators in Python

Division operators.

In Python programming language Division Operators allow you to divide two numbers and return a quotient, i.e., the first number or number at the left is divided by the second number or number at the right and returns the quotient. 

There are two types of division operators: 

Float division

  • Floor division

The quotient returned by this operator is always a float number, no matter if two numbers are integers. For example:

Example: The code performs division operations and prints the results. It demonstrates that both integer and floating-point divisions return accurate results. For example, ’10/2′ results in ‘5.0’ , and ‘-10/2’ results in ‘-5.0’ .

Integer division( Floor division)

The quotient returned by this operator is dependent on the argument being passed. If any of the numbers is float, it returns output in float. It is also known as Floor division because, if any number is negative, then the output will be floored. For example:

Example: The code demonstrates integer (floor) division operations using the // in Python operators . It provides results as follows: ’10//3′ equals ‘3’ , ‘-5//2’ equals ‘-3’ , ‘ 5.0//2′ equals ‘2.0’ , and ‘-5.0//2’ equals ‘-3.0’ . Integer division returns the largest integer less than or equal to the division result.

Precedence of Arithmetic Operators in Python

The precedence of Arithmetic Operators in Python is as follows:

  • P – Parentheses
  • E – Exponentiation
  • M – Multiplication (Multiplication and division have the same precedence)
  • D – Division
  • A – Addition (Addition and subtraction have the same precedence)
  • S – Subtraction

The modulus of Python operators helps us extract the last digit/s of a number. For example:

  • x % 10 -> yields the last digit
  • x % 100 -> yield last two digits

Arithmetic Operators With Addition, Subtraction, Multiplication, Modulo and Power

Here is an example showing how different Arithmetic Operators in Python work:

Example: The code performs basic arithmetic operations with the values of ‘a’ and ‘b’ . It adds (‘+’) , subtracts (‘-‘) , multiplies (‘*’) , computes the remainder (‘%’) , and raises a to the power of ‘b (**)’ . The results of these operations are printed.

Note: Refer to Differences between / and // for some interesting facts about these two Python operators.

Comparison of Python Operators

In Python Comparison of Relational operators compares the values. It either returns True or False according to the condition.

= is an assignment operator and == comparison operator.

Precedence of Comparison Operators in Python

In Python, the comparison operators have lower precedence than the arithmetic operators. All the operators within comparison operators have the same precedence order.

Example of Comparison Operators in Python

Let’s see an example of Comparison Operators in Python.

Example: The code compares the values of ‘a’ and ‘b’ using various comparison Python operators and prints the results. It checks if ‘a’ is greater than, less than, equal to, not equal to, greater than, or equal to, and less than or equal to ‘b’ .

Logical Operators in Python

Python Logical operators perform Logical AND , Logical OR , and Logical NOT operations. It is used to combine conditional statements.

Precedence of Logical Operators in Python

The precedence of Logical Operators in Python is as follows:

  • Logical not
  • logical and

Example of Logical Operators in Python

The following code shows how to implement Logical Operators in Python:

Example: The code performs logical operations with Boolean values. It checks if both ‘a’ and ‘b’ are true ( ‘and’ ), if at least one of them is true ( ‘or’ ), and negates the value of ‘a’ using ‘not’ . The results are printed accordingly.

Bitwise Operators in Python

Python Bitwise operators act on bits and perform bit-by-bit operations. These are used to operate on binary numbers.

Precedence of Bitwise Operators in Python

The precedence of Bitwise Operators in Python is as follows:

  • Bitwise NOT
  • Bitwise Shift
  • Bitwise AND
  • Bitwise XOR

Here is an example showing how Bitwise Operators in Python work:

Example: The code demonstrates various bitwise operations with the values of ‘a’ and ‘b’ . It performs bitwise AND (&) , OR (|) , NOT (~) , XOR (^) , right shift (>>) , and left shift (<<) operations and prints the results. These operations manipulate the binary representations of the numbers.

Python Assignment operators are used to assign values to the variables.

Let’s see an example of Assignment Operators in Python.

Example: The code starts with ‘a’ and ‘b’ both having the value 10. It then performs a series of operations: addition, subtraction, multiplication, and a left shift operation on ‘b’ . The results of each operation are printed, showing the impact of these operations on the value of ‘b’ .

Identity Operators in Python

In Python, is and is not are the identity operators both are used to check if two values are located on the same part of the memory. Two variables that are equal do not imply that they are identical. 

Example Identity Operators in Python

Let’s see an example of Identity Operators in Python.

Example: The code uses identity operators to compare variables in Python. It checks if ‘a’ is not the same object as ‘b’ (which is true because they have different values) and if ‘a’ is the same object as ‘c’ (which is true because ‘c’ was assigned the value of ‘a’ ).

Membership Operators in Python

In Python, in and not in are the membership operators that are used to test whether a value or variable is in a sequence.

Examples of Membership Operators in Python

The following code shows how to implement Membership Operators in Python:

Example: The code checks for the presence of values ‘x’ and ‘y’ in the list. It prints whether or not each value is present in the list. ‘x’ is not in the list, and ‘y’ is present, as indicated by the printed messages. The code uses the ‘in’ and ‘not in’ Python operators to perform these checks.

in Python, Ternary operators also known as conditional expressions are operators that evaluate something based on a condition being true or false. It was added to Python in version 2.5. 

It simply allows testing a condition in a single line replacing the multiline if-else making the code compact.

Syntax :   [on_true] if [expression] else [on_false] 

Examples of Ternary Operator in Python

The code assigns values to variables ‘a’ and ‘b’ (10 and 20, respectively). It then uses a conditional assignment to determine the smaller of the two values and assigns it to the variable ‘min’ . Finally, it prints the value of ‘min’ , which is 10 in this case.

In Python, Operator precedence and associativity determine the priorities of the operator.

Operator Precedence in Python

This is used in an expression with more than one operator with different precedence to determine which operation to perform first.

Let’s see an example of how Operator Precedence in Python works:

Example: The code first calculates and prints the value of the expression 10 + 20 * 30 , which is 610. Then, it checks a condition based on the values of the ‘name’ and ‘age’ variables. Since the name is “ Alex” and the condition is satisfied using the or operator, it prints “Hello! Welcome.”

Operator Associativity in Python

If an expression contains two or more operators with the same precedence then Operator Associativity is used to determine. It can either be Left to Right or from Right to Left.

The following code shows how Operator Associativity in Python works:

Example: The code showcases various mathematical operations. It calculates and prints the results of division and multiplication, addition and subtraction, subtraction within parentheses, and exponentiation. The code illustrates different mathematical calculations and their outcomes.

To try your knowledge of Python Operators, you can take out the quiz on Operators in Python . 

Python Operator Exercise Questions

Below are two Exercise Questions on Python Operators. We have covered arithmetic operators and comparison operators in these exercise questions. For more exercises on Python Operators visit the page mentioned below.

Q1. Code to implement basic arithmetic operations on integers

Q2. Code to implement Comparison operations on integers

Explore more Exercises: Practice Exercise on Operators in Python

Please Login to comment...

Similar reads.

  • python-basics
  • Python-Operators

Improve your Coding Skills with Practice

 alt=

What kind of Experience do you want to share?

IMAGES

  1. Programming example: Copy assignment operator

    when is copy assignment operator used

  2. PPT

    when is copy assignment operator used

  3. Copy Constructor vs Assignment Operator,Difference between Copy Constructor and Assignment Operator

    when is copy assignment operator used

  4. Difference between copy constructor and assignment operator in c++

    when is copy assignment operator used

  5. What is the Difference Between Copy Constructor and Assignment Operator

    when is copy assignment operator used

  6. Difference between Copy Constructor and Assignment Operator,Copy

    when is copy assignment operator used

VIDEO

  1. 029 Copy Assignment Operator for Other Types

  2. 026 Copy Assignment Operator

  3. History copy / assignment first page idea

  4. 043024 COSC 1337 C++ Class Memory Mgmt: copy assignment

  5. 043024 COSC 1337 C++ Class Memory Mgmt: Intro Copy Assignment

  6. How to implement the rule of three's copy constructor

COMMENTS

  1. c++

    A user-declared copy assignment operator X::operator= is a non-static non-template member function of class X with exactly one parameter of type X, X&, const X&, volatile X& or const volatile X&. So for example: struct X {. int a; // an assignment operator which is not a copy assignment operator. X &operator=(int rhs) { a = rhs; return *this ...

  2. Copy assignment operator

    5,6) Definition of a copy assignment operator outside of class definition (the class must contain a declaration (1) ). 6) The copy assignment operator is explicitly-defaulted. The copy assignment operator is called whenever selected by overload resolution, e.g. when an object appears on the left side of an assignment expression.

  3. c++

    An assignment operator is used to replace the data of a previously initialized object with some other object's data. A& operator=(const A& rhs) {data_ = rhs.data_; return *this;} For example: A aa; A a; a = aa; // assignment operator You could replace copy construction by default construction plus assignment, but that would be less efficient.

  4. Copy Constructor vs Assignment Operator in C++

    C++ compiler implicitly provides a copy constructor, if no copy constructor is defined in the class. A bitwise copy gets created, if the Assignment operator is not overloaded. Consider the following C++ program. Explanation: Here, t2 = t1; calls the assignment operator, same as t2.operator= (t1); and Test t3 = t1; calls the copy constructor ...

  5. Everything You Need To Know About The Copy Assignment Operator In C++

    The Copy Assignment Operator in a class is a non-template non-static member function that is declared with the operator=. When you create a class or a type that is copy assignable (that you can copy with the = operator symbol), it must have a public copy assignment operator. Here is a simple syntax for the typical declaration of a copy ...

  6. Copy assignment operator

    The copy assignment operator selected for every non-static class type (or array of class type) memeber of T is trivial. A trivial copy assignment operator makes a copy of the object representation as if by std::memmove. All data types compatible with the C language (POD types) are trivially copy-assignable.

  7. Copy constructors and copy assignment operators (C++)

    Use an assignment operator operator= that returns a reference to the class type and takes one parameter that's passed by const reference—for example ClassName& operator=(const ClassName& x);. Use the copy constructor. If you don't declare a copy constructor, the compiler generates a member-wise copy constructor for you.

  8. Copy assignment operator

    Typical declaration of a copy assignment operator when copy-and-swap idiom cannot be used (non-swappable type or degraded performance). Forcing a copy assignment operator to be generated by the compiler. Avoiding implicit copy assignment. The copy assignment operator is called whenever selected by overload resolution, e.g. when an object ...

  9. Copy assignment operator

    A copy assignment operator of class T is a non-template non-static member function with the name operator= that takes exactly one parameter of type T, T&, const T&, volatile T&, or const volatile T&. For a type to be CopyAssignable, it must have a public copy assignment operator.

  10. Copy Assignment Operator

    Triviality of eligible copy assignment operators determines whether the class is a trivially copyable type.. Implicitly-defined copy assignment operator. If the implicitly-declared copy assignment operator is neither deleted nor trivial, it is defined (that is, a function body is generated and compiled) by the compiler if odr-used or needed for constant evaluation (since C++14).

  11. Copy constructors, assignment operators,

    The first line runs the copy constructor of T, which can throw; the remaining lines are assignment operators which can also throw. HOWEVER, if you have a type T for which the default std::swap() may result in either T's copy constructor or assignment operator throwing, you are

  12. 21.12

    21.12 — Overloading the assignment operator. Alex November 27, 2023. The copy assignment operator (operator=) is used to copy values from one object to another already existing object. As of C++11, C++ also supports "Move assignment". We discuss move assignment in lesson 22.3 -- Move constructors and move assignment .

  13. PDF Copy Constructors and Assignment Operators

    Assignment Operators While the copy constructor is used to set up a new version of an object that's a duplicate of another object, the assignment operator is used to overwrite the value of an already-created object with the contents of another class instance.

  14. Assignment operators

    for assignments to class type objects, the right operand could be an initializer list only when the assignment is defined by a user-defined assignment operator. removed user-defined assignment constraint. CWG 1538. C++11. E1 ={E2} was equivalent to E1 = T(E2) ( T is the type of E1 ), this introduced a C-style cast. it is equivalent to E1 = T{E2}

  15. 22.3

    Copy constructors are used to initialize a class by making a copy of an object of the same class. Copy assignment is used to copy one class object to another existing class object. By default, C++ will provide a copy constructor and copy assignment operator if one is not explicitly provided.

  16. Assignment operator (C++)

    Assignment operator (C++) In the C++ programming language, the assignment operator, =, is the operator used for assignment. Like most other operators in C++, it can be overloaded . The copy assignment operator, often just called the "assignment operator", is a special case of assignment operator where the source (right-hand side) and ...

  17. Copy assignment operator

    The copy assignment operator selected for every non-static class type (or array of class type) memeber of T is trivial T has no non-static data members of volatile-qualified type (since C++14) A trivial copy assignment operator makes a copy of the object representation as if by std::memmove. All data types compatible with the C language (POD ...

  18. Assignment Operators In C++

    Prerequisite: Operator Overloading The assignment operator,"=", is the operator used for Assignment. It copies the right value into the left value. Assignment Operators are predefined to operate only on built-in Data types. ... If a class doesn't contain pointers, then there is no need to write assignment operator and copy constructor. The ...

  19. Copy Constructor in C++

    A copy constructor is called when a new object is created from an existing object, as a copy of the existing object. The assignment operator is called when an already initialized object is assigned a new value from another existing object. In the above example (1) calls the copy constructor and (2) calls the assignment operator.

  20. When is the copy assignment operator called?

    Test c = b is an initialization, not an assignment. If you had done this: Test c; c = b; Then it would have called the copy assignment operator. edited Jan 19, 2016 at 15:35. answered Mar 19, 2015 at 20:58. Emil Laine.

  21. Python Operators

    Assignment Operators in Python. Let's see an example of Assignment Operators in Python. Example: The code starts with 'a' and 'b' both having the value 10. It then performs a series of operations: addition, subtraction, multiplication, and a left shift operation on 'b'.

  22. c++

    Nov 1, 2020 at 19:23. 1. That isn't correct. type var=init; declares a variable named var of type type, and initializes it with the expression init; this is not an assignment, and never uses operator=. var = value; performs an assignment of value to the variable. It's not as simple as "look for equal sign".