cppreference.com

Copy assignment operator.

(C++20)
(C++20)
(C++11)
(C++11)
(C++11)
(C++17)
General
Members
pointer
(C++11)
specifier
specifier
Special member functions
(C++11)
(C++11)
Inheritance
(C++11)
(C++11)

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.

Syntax Explanation Implicitly-declared copy assignment operator Deleted implicitly-declared copy assignment operator Trivial copy assignment operator Implicitly-defined copy assignment operator Notes Example Defect reports

[ edit ] Syntax

class_name class_name ( class_name ) (1)
class_name class_name ( const class_name ) (2)
class_name class_name ( const class_name ) = default; (3) (since C++11)
class_name class_name ( const class_name ) = delete; (4) (since C++11)

[ 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)

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.

[ 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 (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;
has no non-static data members of -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 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 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.

[ edit ] Example

[ edit ] defect reports.

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

DR Applied to Behavior as published Correct behavior
C++14 operator=(X&) = default was non-trivial made trivial
  • Pages with unreviewed CWG DR marker
  • 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 9 January 2019, at 07:16.
  • This page has been accessed 570,566 times.
  • Privacy policy
  • About cppreference.com
  • Disclaimers

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?

Additional resources

  • 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

*

MyClass& other ); MyClass( MyClass& other ); MyClass( MyClass& other ); MyClass( MyClass& other );
MyClass* other );
MyClass { x; c; std::string s; };
MyClass& other ) : x( other.x ), c( other.c ), s( other.s ) {}
);
print_me_bad( std::string& s ) { std::cout << s << std::endl; } print_me_good( std::string& s ) { std::cout << s << std::endl; } std::string hello( ); print_me_bad( hello ); print_me_bad( std::string( ) ); print_me_bad( ); print_me_good( hello ); print_me_good( std::string( ) ); print_me_good( );
, );
=( MyClass& other ) { x = other.x; c = other.c; s = other.s; * ; }
< T > MyArray { size_t numElements; T* pElements; : size_t count() { numElements; } MyArray& =( MyArray& rhs ); };
<> MyArray<T>:: =( MyArray& rhs ) { ( != &rhs ) { [] pElements; pElements = T[ rhs.numElements ]; ( size_t i = 0; i < rhs.numElements; ++i ) pElements[ i ] = rhs.pElements[ i ]; numElements = rhs.numElements; } * ; }
<> MyArray<T>:: =( MyArray& rhs ) { MyArray tmp( rhs ); std::swap( numElements, tmp.numElements ); std::swap( pElements, tmp.pElements ); * ; }
< T > swap( T& one, T& two ) { T tmp( one ); one = two; two = tmp; }
<> MyArray<T>:: =( MyArray tmp ) { std::swap( numElements, tmp.numElements ); std::swap( pElements, tmp.pElements ); * ; }
  • C++ Data Types
  • C++ Input/Output
  • C++ Pointers
  • C++ Interview Questions
  • C++ Programs
  • C++ Cheatsheet
  • C++ Projects
  • C++ Exception Handling
  • C++ Memory Management

Copy Constructor vs Assignment Operator in C++

Copy constructor and Assignment operator are similar as they are both used to initialize one object using another object. But, there are some basic differences between them:

Copy constructor Assignment operator 
It is called when a new object is created from an existing object, as a copy of the existing objectThis operator is called when an already initialized object is assigned a new value from another existing object. 
It creates a separate memory block for the new object.It does not automatically create a separate memory block or new memory space. However, if the class involves dynamic memory management, the assignment operator must first release the existing memory on the left-hand side and then allocate new memory as needed to copy the data from the right-hand side.
It is an overloaded constructor.It is a bitwise operator. 
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. 

className(const className &obj) {

// body 

}

 

className obj1, obj2;

obj2 = obj1;

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 , same as Test t3(t1);

Must Read: When is a Copy Constructor Called in C++?

Please Login to comment...

Similar reads.

  • Discord Emojis List 2024: Copy and Paste
  • Best Adblockers for Twitch TV: Enjoy Ad-Free Streaming in 2024
  • PS4 vs. PS5: Which PlayStation Should You Buy in 2024?
  • Best Mobile Game Controllers in 2024: Top Picks for iPhone and Android
  • System Design Netflix | A Complete Architecture

Improve your Coding Skills with Practice

 alt=

What kind of Experience do you want to share?

22.3 — Move constructors and move assignment

Related content

Notably, this means that pointers will be copied, not moved!

Move functions should always leave both objects in a valid state

  • Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers
  • Advertising & Talent Reach devs & technologists worldwide about your product, service or employer brand
  • OverflowAI GenAI features for Teams
  • OverflowAPI Train & fine-tune LLMs
  • Labs The future of collective knowledge sharing
  • About the company Visit the blog

Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Get early access and see previews of new features.

Using copy constructor and copy assignment operator for pointers to dynamically allocated memory

I was looking at an explanation of the Rule of Three, and found the following code:

explaining things (found here: What is The Rule of Three? ) I wasn't sure if I should ask the question there (since it's been a while since it was posted) or to make a new question, so I hope I don't get in trouble. I just want to see if I understood this code correctly?

From what I'm understanding here is that instead of copying the pointers (and thus having two objects point to the same memory), the object being copied to is dynamically allocating new memory which will then contain the same data that the object that was copy contains? And what is the reason that the copy assignment operator function has "delete [] name]" at the beginning? Is it because when = is used, the pointer is automatically copied and thus this new object points to the same memory as the object copied, and delete [] name deletes that memory before dynamically allocating new memory for it to point to? Actually, I'm not really sure what I'm saying so can somebody explain to me why it uses delete? And finally, what is the purpose of the if (this != &that) part?

Community's user avatar

  • You probably need to look at the Rule of Zero question and its related article . –  Open AI - Opting Out Commented Nov 16, 2013 at 22:59

4 Answers 4

The point of the delete is to free the memory previously owned by the this object for the name field. Notice that this is the assignment operator overloading, i.e:

Would call the function with this == &x and that == &y .

This copies y's inner members to x while making sure to free any dynamically allocated memory previously allocated to x.name

ordahan's user avatar

  • and this would only apply if the object being copied to previously did have its pointer member already pointing at something. If the object is newly created and assigned the value of another object, it wouldn't need to worry about that at all..did I understand that correctly? @ordahan –  FrostyStraw Commented Nov 16, 2013 at 23:22
  • wait, upon further research I realized that a copy constructor is used to initialize a previously uninitialized object from some other object's date, so since it was previously uninitiliazed, it doesn't need to delete anything... –  FrostyStraw Commented Nov 17, 2013 at 0:41

The member variable name is a pointer. It (almost always) points to a char[] that was allocated on the heap (that is, with new ).

We want to copy the name of the other object to this one:

But before that we must make sure that the array which name points to is big enough to hold the new name (and a terminating '\0'), so we allocate space with new :

But what about the space that name previously pointed to? We don't want to just abandon it, that would be a memory leak , so we should delete it before reassigning the pointer:

As for this != &that , consider what would happen if some careless person used the assignment operator from one person to itself ( Alice = Alice ). Work through the steps and you'll see that the name would be entirely lost.

Beta's user avatar

First off, this assignment operator is a bad example ! In particular it is not thread-safe! If you want to write a proper assignment operator, you write it like this:

where swap() is a member function you want anyway, simply swapping all members:

With respect to your questions:

  • The idea of this comparison is to guard against self-assignment. If the code following this check actually depends on this check being present to be correct, it is almost certainly not exception safe (rarely, the code afterwards provides the basic guarantee; I have never seen an example where it ends up implementing the strong exception safety guarantee although there is no reason for the assignment operator to not implement the strong exception safety guarantee).
  • If the code is just there and not strictly needed it is "optimizing" the self-assignment case. ... and impacting all cases where where the assignment is not a self-assignment which is, hopefully, the vast majority! If your code is mostly busy assigning objects to themselves, there is something more fundamental broken in the code.
  • You can allocate individual objects using new T(args) or new T{args} where T is not a typedef for an array type, and args is a placeholder for the constructor arguments. Memory thus allocated needs to be release using delete ptr where ptr is the result returned from the expression above. Typically, the memory is not release explicitly but passed to an object which takes care of releasing the memory, e.g., std::unique_ptr<T>(new T(args)) : the destructor of std::unique_ptr<T> will call delete as needed.
  • You can allocate an array object, typically using new T[n] where n is the size of the array. Objects thus allocated need to be released using delete[] array where array is the result returned from the array allocation. This is rarely seen as normally you'd rather use std::string or std::vector<T> to allocate arrays. You can also use the class template mentioned above but you need to indicate that you need to release an array: std::unique_ptr<T[]>(new T[n]) .

Dietmar Kühl's user avatar

  • An assignment operator that modifies the RHS? That's... I can't seem to find the right words. Have I completely misunderstood what you wrote, or are you proposing something completely at odds with convention? –  Beta Commented Nov 17, 2013 at 0:01
  • @Beta: Please note the the RHS is passed by copy , not by reference! That is, the assignment operator leverages the copy constructor (when the argument is passed) to create a copy the RHS, the swap() method to exchange the current representation with that of the copy, and the destructor (when the argument is destroy) to get rid of the original content of the LHS. Yes, it is somewhat dense but it does exactly what is wanted which includes meeting the strong exception guarantee (assuming swap() can't throw). –  Dietmar Kühl Commented Nov 17, 2013 at 0:04
  • Ah! So I did completely misunderstand-- what a relief! –  Beta Commented Nov 17, 2013 at 0:56
  • @Beta: I hope it isn't just a relief but also an epiphany! This assignment operator is a piece of elegance. The only fly in the ointment is that it needs to be typed out for each class needing an assignment operator! Of course, given its beauty that is kind of acceptable. –  Dietmar Kühl Commented Nov 17, 2013 at 1:02

The reason for delete[] name; is that the class invariant is that name points to a dynamically allocated buffer sized exactly for the person's name. Notice that we're about to create a new buffer to accommodate our copy of the data stored in that.name . If we didn't delete[] what our original name was pointing to, we'd leak that memory.

As for if (this != &that) , simply mentally trace what would happen if this wasn't there and someone called x = x on a person x object. First, we delete[] name . Since this == &that , this also means this->name == that.name , so we've invalidated the buffer pointed to by that.name as well. In the next step, we call strlen() on the (now invalidated) buffer, which gives Undefined Behaviour (could be e.g. a segfault).

Angew is no longer proud of SO's user avatar

Your Answer

Reminder: Answers generated by artificial intelligence tools are not allowed on Stack Overflow. Learn more

Sign up or log in

Post as a guest.

Required, but never shown

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy .

Not the answer you're looking for? Browse other questions tagged c++ pointers memory or ask your own question .

  • The Overflow Blog
  • The hidden cost of speed
  • The creator of Jenkins discusses CI/CD and balancing business with open source
  • Featured on Meta
  • Announcing a change to the data-dump process
  • Bringing clarity to status tag usage on meta sites
  • What does a new user need in a homepage experience on Stack Overflow?
  • Feedback requested: How do you use tag hover descriptions for curating and do...
  • Staging Ground Reviewer Motivation

Hot Network Questions

  • Visual assessment of scatterplots acceptable?
  • "Mixture, Pitch then Power" - why?
  • Calculating greeks by finite difference in MC simulation
  • Best approach to make lasagna fill pan
  • Is there a non-semistable simple sheaf?
  • Is reading sheet music difficult?
  • Representing permutation groups as equivalence relations
  • How should I tell my manager that he could delay my retirement with a raise?
  • Star Trek: The Next Generation episode that talks about life and death
  • Intersection of Frobenius subalgebra objects
  • How should αἱμάτων in John 1:13 be interpreted: “not of blood” or “not of bloods”?
  • Why is it spelled "dummy" and not "dumby?"
  • Children in a field trapped under a transparent dome who interact with a strange machine inside their car
  • Bike helmet not small enough
  • Wien's displacement law
  • IRF9540N P-MOSFET Heating UP
  • Manhattan distance
  • Replacing jockey wheels on Shimano Deore rear derailleur
  • The question about the existence of an infinite non-trivial controversy
  • Does a party have to wait 1d4 hours to start a Short Rest if no healing is available and an ally is only stabilized?
  • In a tabular with p-column, line spacing after multi-line cell too short with the array package
  • What was the first "Star Trek" style teleporter in SF?
  • How does the phrase "a longe" meaning "from far away" make sense syntactically? Shouldn't it be "a longo"?
  • Current in a circuit is 50% lower than predicted by Kirchhoff's law

c copy assignment operator pointer

IMAGES

  1. Pointer Expressions in C with Examples

    c copy assignment operator pointer

  2. Pointer Expressions in C with Examples

    c copy assignment operator pointer

  3. What is assignment operator in C with example?

    c copy assignment operator pointer

  4. Expressions de pointeur en C avec exemples

    c copy assignment operator pointer

  5. Pointers in C++: The Ultimate Step-by-Step Guide

    c copy assignment operator pointer

  6. C++ Tutorial: Operator Overloading Part 5

    c copy assignment operator pointer

VIDEO

  1. Assignment Operator in C Programming

  2. Indirection (*) and Address of (&) operator

  3. Augmented assignment operators in C

  4. Assignment Operator in C Programming

  5. Assignment Operator Overloading In C++

  6. C Programming Tutorial

COMMENTS

  1. Copy assignment operator - cppreference.com

    Copy assignment operator. A copy assignment operator is a non-template non-static member function with the name operator= that can be called with an argument of the same class type and copies the content of the argument without mutating the argument.

  2. c++ - The copy constructor and assignment operator - Stack ...

    The assignment operator is used to change an existing instance to have the same values as the rvalue, which means that the instance has to be destroyed and re-initialized if it has internal dynamic memory. Useful link : Copy Constructors, Assignment Operators, and More; Copy constructor and = operator overload in C++: is a common function possible?

  3. 21.12 — Overloading the assignment operator – Learn C++

    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 .

  4. Copy assignment operator - cppreference.com - man6.org

    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. Syntax. Explanation.

  5. 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.

  6. Copy constructors, assignment operators, - C++ Articles

    What is a copy constructor? A copy constructor is a special constructor for a class/struct that is used to make a copy of an existing instance. According to the C++ standard, the copy constructor for MyClass must have one of the following signatures:

  7. Copy Constructor vs Assignment Operator in C++ - GeeksforGeeks

    Copy constructor and Assignment operator are similar as they are both used to initialize one object using another object. But, there are some basic differences between them: Copy constructor. Assignment operator. It is called when a new object is created from an existing object, as a copy of the existing object.

  8. Assignment operators - cppreference.com

    Copy assignment replaces the contents of the object a with a copy of the contents of b (b is not modified). For class types, this is performed in a special member function, described in copy assignment operator.

  9. Move constructors and move assignment – Learn C++">22.3 — Move constructors and move assignment – Learn C++

    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.

  10. c++ - Using copy constructor and copy assignment operator for ...">c++ - Using copy constructor and copy assignment operator for ...

    That is, the assignment operator leverages the copy constructor (when the argument is passed) to create a copy the RHS, the swap() method to exchange the current representation with that of the copy, and the destructor (when the argument is destroy) to get rid of the original content of the LHS.