• Sign In / Suggest an Article

Current ISO C++ status

Upcoming ISO C++ meetings

Upcoming C++ conferences

Compiler conformance status

ISO C++ committee meeting

March 18-23, Tokyo, Japan

April 17-20, Bristol, UK

using std::cpp 2024

April 24-26, Leganes, Spain

Pure Virtual C++ 2024

April 30, Online  

C++ Now 2024

May 7-12, Aspen, CO, USA

June 24-29, St. Louis, MO, USA

July 2-5, Folkestone, Kent, UK

Quick Q: Most concise way to disable copy and move semantics

By Adrien Hamelin | Feb 20, 2018 08:40 AM | Tags: c++11 advanced

Quick A: Delete the move assignment.

Recently on SO:

Most concise way to disable copy and move semantics According to this chart (by Howard Hinnant): The most concise way is to =delete move assignment operator (or move constructor, but it can cause problems mentioned in comments). Though, in my opinion the most readable way is to =delete both copy constructor and copy assignment operator.

Share this Article

Add a comment, comments (0).

There are currently no comments on this entry.

cppreference.com

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)

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;

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.

  • 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

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

  • C++ Classes and Objects
  • C++ Polymorphism
  • C++ Inheritance
  • C++ Abstraction
  • C++ Encapsulation
  • C++ OOPs Interview Questions
  • C++ OOPs MCQ
  • C++ Interview Questions
  • C++ Function Overloading
  • C++ Programs
  • C++ Preprocessor
  • C++ Templates
  • When is a Copy Constructor Called in C++?
  • Dynamic Constructor in C++ with Examples
  • C++ 17 | New ways to Assign values to Variables
  • Constructor Delegation in C++
  • Copy-and-Swap Idiom in C++
  • Copy Constructor in C++
  • When Does Compiler Create Default and Copy Constructors in C++?
  • Can a constructor be private in C++ ?
  • Placement new operator in C++
  • User Defined Literals in C++
  • Rule Of Three in C++
  • Constructors in C++
  • C++ Interview questions based on constructors/ Destructors.
  • How to make a C++ class whose objects can only be dynamically allocated?
  • std::any Class in C++
  • Advanced C++ with Boost Library
  • Using class to implement Vector Quantities in C++
  • Undefined Behavior in C and C++
  • Constructor Overloading in C++

Preventing Object Copy in C++ (3 Different Ways)

Many times, user wants that an instance of a C++ class should not be copied at all. So, the question is how do we achieve this ?

There are three ways to achieve this :

Below is the C++ implementation to illustrate how this can be done.

NOTE: This code does not compile as we cannot copy the object of this class and hence it will show this error.

Below is the C++ implementation to illustrate :

Reference: https://ariya.io/2015/01/c-class-and-preventing-object-copy

Please Login to comment...

Similar reads.

  • cpp-advanced
  • cpp-constructor
  • What are Tiktok AI Avatars?
  • Poe Introduces A Price-per-message Revenue Model For AI Bot Creators
  • Truecaller For Web Now Available For Android Users In India
  • Google Introduces New AI-powered Vids App
  • 30 OOPs Interview Questions and Answers (2024)

Improve your Coding Skills with Practice

 alt=

What kind of Experience do you want to share?

Learn C++

21.12 — Overloading the assignment operator

The copy assignment operator (operator=) is used to copy values from one object to another already existing object .

Related content

As of C++11, C++ also supports “Move assignment”. We discuss move assignment in lesson 22.3 -- Move constructors and move assignment .

Copy assignment vs Copy constructor

The purpose of the copy constructor and the copy assignment operator are almost equivalent -- both copy one object to another. However, the copy constructor initializes new objects, whereas the assignment operator replaces the contents of existing objects.

The difference between the copy constructor and the copy assignment operator causes a lot of confusion for new programmers, but it’s really not all that difficult. Summarizing:

  • If a new object has to be created before the copying can occur, the copy constructor is used (note: this includes passing or returning objects by value).
  • If a new object does not have to be created before the copying can occur, the assignment operator is used.

Overloading the assignment operator

Overloading the copy assignment operator (operator=) is fairly straightforward, with one specific caveat that we’ll get to. The copy assignment operator must be overloaded as a member function.

This prints:

This should all be pretty straightforward by now. Our overloaded operator= returns *this, so that we can chain multiple assignments together:

Issues due to self-assignment

Here’s where things start to get a little more interesting. C++ allows self-assignment:

This will call f1.operator=(f1), and under the simplistic implementation above, all of the members will be assigned to themselves. In this particular example, the self-assignment causes each member to be assigned to itself, which has no overall impact, other than wasting time. In most cases, a self-assignment doesn’t need to do anything at all!

However, in cases where an assignment operator needs to dynamically assign memory, self-assignment can actually be dangerous:

First, run the program as it is. You’ll see that the program prints “Alex” as it should.

Now run the following program:

You’ll probably get garbage output. What happened?

Consider what happens in the overloaded operator= when the implicit object AND the passed in parameter (str) are both variable alex. In this case, m_data is the same as str.m_data. The first thing that happens is that the function checks to see if the implicit object already has a string. If so, it needs to delete it, so we don’t end up with a memory leak. In this case, m_data is allocated, so the function deletes m_data. But because str is the same as *this, the string that we wanted to copy has been deleted and m_data (and str.m_data) are dangling.

Later on, we allocate new memory to m_data (and str.m_data). So when we subsequently copy the data from str.m_data into m_data, we’re copying garbage, because str.m_data was never initialized.

Detecting and handling self-assignment

Fortunately, we can detect when self-assignment occurs. Here’s an updated implementation of our overloaded operator= for the MyString class:

By checking if the address of our implicit object is the same as the address of the object being passed in as a parameter, we can have our assignment operator just return immediately without doing any other work.

Because this is just a pointer comparison, it should be fast, and does not require operator== to be overloaded.

When not to handle self-assignment

Typically the self-assignment check is skipped for copy constructors. Because the object being copy constructed is newly created, the only case where the newly created object can be equal to the object being copied is when you try to initialize a newly defined object with itself:

In such cases, your compiler should warn you that c is an uninitialized variable.

Second, the self-assignment check may be omitted in classes that can naturally handle self-assignment. Consider this Fraction class assignment operator that has a self-assignment guard:

If the self-assignment guard did not exist, this function would still operate correctly during a self-assignment (because all of the operations done by the function can handle self-assignment properly).

Because self-assignment is a rare event, some prominent C++ gurus recommend omitting the self-assignment guard even in classes that would benefit from it. We do not recommend this, as we believe it’s a better practice to code defensively and then selectively optimize later.

The copy and swap idiom

A better way to handle self-assignment issues is via what’s called the copy and swap idiom. There’s a great writeup of how this idiom works on Stack Overflow .

The implicit copy assignment operator

Unlike other operators, the compiler will provide an implicit public copy assignment operator for your class if you do not provide a user-defined one. This assignment operator does memberwise assignment (which is essentially the same as the memberwise initialization that default copy constructors do).

Just like other constructors and operators, you can prevent assignments from being made by making your copy assignment operator private or using the delete keyword:

Note that if your class has const members, the compiler will instead define the implicit operator= as deleted. This is because const members can’t be assigned, so the compiler will assume your class should not be assignable.

If you want a class with const members to be assignable (for all members that aren’t const), you will need to explicitly overload operator= and manually assign each non-const member.

guest

This browser is no longer supported.

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

Explicitly Defaulted and Deleted Functions

  • 8 contributors

In C++11, defaulted and deleted functions give you explicit control over whether the special member functions are automatically generated. Deleted functions also give you simple language to prevent problematic type promotions from occurring in arguments to functions of all types—special member functions, and normal member functions and nonmember functions—which would otherwise cause an unwanted function call.

Benefits of explicitly defaulted and deleted functions

In C++, the compiler automatically generates the default constructor, copy constructor, copy-assignment operator, and destructor for a type if it doesn't declare its own. These functions are known as the special member functions , and they're what make simple user-defined types in C++ behave like structures do in C. That is, you can create, copy, and destroy them without extra coding effort. C++11 brings move semantics to the language and adds the move constructor and move-assignment operator to the list of special member functions that the compiler can automatically generate.

This is convenient for simple types, but complex types often define one or more of the special member functions themselves, and this can prevent other special member functions from being automatically generated. In practice:

If any constructor is explicitly declared, then no default constructor is automatically generated.

If a virtual destructor is explicitly declared, then no default destructor is automatically generated.

If a move constructor or move-assignment operator is explicitly declared, then:

No copy constructor is automatically generated.

No copy-assignment operator is automatically generated.

If a copy constructor, copy-assignment operator, move constructor, move-assignment operator, or destructor is explicitly declared, then:

No move constructor is automatically generated.

No move-assignment operator is automatically generated.

Additionally, the C++11 standard specifies the following additional rules:

  • If a copy constructor or destructor is explicitly declared, then automatic generation of the copy-assignment operator is deprecated.
  • If a copy-assignment operator or destructor is explicitly declared, then automatic generation of the copy constructor is deprecated.

In both cases, Visual Studio continues to automatically generate the necessary functions implicitly, and doesn't emit a warning by default. Since Visual Studio 2022 version 17.7, C5267 can be enabled to emit a warning.

The consequences of these rules can also leak into object hierarchies. For example, if for any reason a base class fails to have a default constructor that's callable from a deriving class—that is, a public or protected constructor that takes no parameters—then a class that derives from it can't automatically generate its own default constructor.

These rules can complicate the implementation of what should be straight-forward, user-defined types and common C++ idioms—for example, making a user-defined type noncopyable by declaring the copy constructor and copy-assignment operator privately and not defining them.

Before C++11, this code snippet was the idiomatic form of noncopyable types. However, it has several problems:

The copy constructor has to be declared privately to hide it, but because it's declared at all, automatic generation of the default constructor is prevented. You have to explicitly define the default constructor if you want one, even if it does nothing.

Even if the explicitly defined default constructor does nothing, the compiler considers it to be nontrivial. It's less efficient than an automatically generated default constructor and prevents noncopyable from being a true POD type.

Even though the copy constructor and copy-assignment operator are hidden from outside code, the member functions and friends of noncopyable can still see and call them. If they're declared but not defined, calling them causes a linker error.

Although this is a commonly accepted idiom, the intent isn't clear unless you understand all of the rules for automatic generation of the special member functions.

In C++11, the noncopyable idiom can be implemented in a way that is more straightforward.

Notice how the problems with the pre-C++11 idiom are resolved:

Generation of the default constructor is still prevented by declaring the copy constructor, but you can bring it back by explicitly defaulting it.

Explicitly defaulted special member functions are still considered trivial, so there's no performance penalty, and noncopyable isn't prevented from being a true POD type.

The copy constructor and copy-assignment operator are public but deleted. It's a compile-time error to define or call a deleted function.

The intent is clear to anyone who understands =default and =delete . You don't have to understand the rules for automatic generation of special member functions.

Similar idioms exist for making user-defined types that are nonmovable, that can only be dynamically allocated, or that can't be dynamically allocated. Each of these idioms have pre-C++11 implementations that suffer similar problems, and that are similarly resolved in C++11 by implementing them in terms of defaulted and deleted special member functions.

Explicitly defaulted functions

You can default any of the special member functions—to explicitly state that the special member function uses the default implementation, to define the special member function with a nonpublic access qualifier, or to reinstate a special member function whose automatic generation was prevented by other circumstances.

You default a special member function by declaring it as in this example:

Notice that you can default a special member function outside the body of a class as long as it's inlinable.

Because of the performance benefits of trivial special member functions, we recommend that you prefer automatically generated special member functions over empty function bodies when you want the default behavior. You can do this either by explicitly defaulting the special member function, or by not declaring it (and also not declaring other special member functions that would prevent it from being automatically generated.)

Deleted functions

You can delete special member functions and normal member functions and nonmember functions to prevent them from being defined or called. Deleting of special member functions provides a cleaner way of preventing the compiler from generating special member functions that you don't want. The function must be deleted as it's declared; it can't be deleted afterwards in the way that a function can be declared and then later defaulted.

Deleting of normal member function or nonmember functions prevents problematic type promotions from causing an unintended function to be called. This works because deleted functions still participate in overload resolution and provide a better match than the function that could be called after the types are promoted. The function call resolves to the more-specific—but deleted—function and causes a compiler error.

Notice in the preceding sample that calling call_with_true_double_only by using a float argument would cause a compiler error, but calling call_with_true_double_only by using an int argument wouldn't; in the int case, the argument will be promoted from int to double and successfully call the double version of the function, even though that might not be what you intend. To ensure that any call to this function by using a non-double argument causes a compiler error, you can declare a template version of the deleted function.

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 (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

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

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 copy assignment operator for class T is trivial if all of the following is true:

  • The operator 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) 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

C++ Class and Preventing Object Copy

Jan 10, 2015 4 min read #c++ #coding

clonetroopers

A class that represents a wrapper stream of a file should not have its instance copied around. It will cause a confusion in the handling of the actual I/O system. In a similar spirit, if an instance holds a unique private object, copying the pointer does not make sense. A somehow related problem but not necessarily similar is the issue of object slicing .

The following illustration demonstrates a simple class Vehicle that is supposed to have a unique owner, an instance of Person .

For this purpose, the implementation of Person is as simple as:

To show the issue, a helper function info() is implement as follows:

From this example, it is obvious that an instance of Car must not be copied. In particular, another clone of a similar car should not automatically belong to the same owner. In fact, running the subsequent code:

will give the output:

How can we prevent this accidental object copy?

Method 1: Private copy constructor and copy assignment operator

A very common technique is to declare both the copy constructor and copy assignment operator to be private. We do not even need to implement them. The idea is so that any attempt to perform a copy or an assignment will provoke a compile error.

In the above example, Car will be modified to look like the following. Take a look closely at two additional private members of the class.

Now if we try again to assign an instance of Car to a new one, the compiler will complain loudly:

If writing two additional lines containing repetitive names is too cumbersome, a macro could be utilized instead. This is the approach used by WebKit, see its WTF_MAKE_NONCOPYABLE macro from wtf/Noncopyable.h (do not be alarmed, in the context of WebKit source code , WTF here stands for Web Template Framework). Chromium code, as shown in the file base/macros.h , distinguishes between copy constructor and assignment, denoted as DISALLOW_COPY and DISALLOW_ASSIGN macros, respectively.

Method 2: Non-copyable mixin

The idea above can be extended to create a dedicated class which has the sole purpose to prevent object copying. It is often called as Noncopyable and typically used as a mixin . In our example, the Car class can then be derived from this Noncopyable .

Boost users may be already familiar with boost::noncopyable , the Boost flavor of the said mixin. A conceptual, self-contained implementation of that mixin will resemble something like the following:

Our lovely Car class can be written as:

Compared to the first method, using Noncopyable has the benefit of making the intention very clear. A quick glance at the class, right on its first line, and you know right away that its instance is not supposed to be copied.

Method 3: Deleted copy constructor and copy assignment operator

For modern applications, there is less and less reason to get stuck with the above workaround. Thanks to C++11, the solution becomes magically simple: just delete the copy constructor and assignment operator. Our class will look like this instead:

Note that if you use boost::noncopyable mixin with a compiler supporting C++11, the implementation of boost::noncopyable also automatically deletes the said member functions.

With this approach, any accidental copy will result in a quite friendlier error message:

So, which of the above three methods is your favorite?

Related posts:

  • First Look: Kotlin Native
  • Debian on Windows via WSL
  • Windows for Web Development
  • Syntax Highlighting in the Terminal
  • Continuous Tests of Downstream Projects
  • Detecting and Automatically Fixing JavaScript Code Style

♡ this article? Explore more articles and follow me Twitter .

Share this on Twitter Facebook

How to prevent object copy in C++

c prevent copy assignment operator

In this tutorial, we will learn how to prevent object copy in C++. This can be done in 3 ways and we shall implement each of these.

Making the access specifier of Copy constructor and Copy assignment operator private

Here, when we are calling the copy constructor and copy assignment operator we encounter an error. This is because these two are private. Thus preventing object copying.

Deleting the Copy constructor and Copy assignment operator

We have deleted both the copy constructor and the copy assignment operator so, while calling them we get errors. Thus preventing object copying.

Through inheritance i.e., by making the Copy constructor and Copy assignment operator private in the base class

Both the copy constructor and the copy assignment operator are private in the Base class thus preventing object copying and producing error while doing so.

This is how we prevent object copy in C++.

You may also read, Copy Constructor in C++ Inheritance in C++

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Please enable JavaScript to submit this form.

Related Posts

  • Singleton in C++
  • Passing object by reference in C++
  • How to create an object in C++

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.

IMAGES

  1. Assignment Operators in C » PREP INSTA

    c prevent copy assignment operator

  2. Assignment Operators in C

    c prevent copy assignment operator

  3. C programming +=

    c prevent copy assignment operator

  4. Assignment Operators in C Programming

    c prevent copy assignment operator

  5. Assignment Operators in C Example

    c prevent copy assignment operator

  6. [100% Working Code]

    c prevent copy assignment operator

VIDEO

  1. 如何用讀寫鎖實作 thread safe copy constructor and copy assignment?

  2. Assignment Operator in C Programming

  3. Assignment Operator in C Programming

  4. Обучение C++. Урок 27. Директивы препроцессора. Часть II

  5. #003 Lec3

  6. LeadSquared Product Updates: Learn What’s New!

COMMENTS

  1. Most concise way to disable copying class in C++11

    13. Deleting the copy-constructor and copy-assignment operator is the simplest and clearest way to disable copying: class X. {. X(X const &) = delete; void operator=(X const &x) = delete; }; I don't follow what you are talking about with virtual destructors in the question body .

  2. c++

    The alternative is to declare a copy-constructor private and leave it undefined, or define it with a BOOST_STATIC_ASSERT(false). If you are working with C++11 you can also delete your copy constructor: class nocopy. {. nocopy( nocopy const& ) = delete; }; answered Oct 19, 2011 at 15:37. K-ballo.

  3. Copy assignment operator

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

  4. Quick Q: Most concise way to disable copy and move semantics

    Most concise way to disable copy and move semantics. According to this chart (by Howard Hinnant): The most concise way is to =delete move assignment operator (or move constructor, but it can cause problems mentioned in comments). Though, in my opinion the most readable way is to =delete both copy constructor and copy assignment operator.

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

  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. Preventing Object Copy in C++ (3 Different Ways)

    Using Deleted copy constructor and copy assignment operator: Above two ways are quite complex, C++11 has come up with a simpler solution i.e. just delete the copy constructor and assignment operator. 'Base::Base(const Base&)'. Base b2(b1); // Calls copy constructor. Base(const Base &temp_obj) = delete;

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

  10. Explicitly Defaulted and Deleted Functions

    Benefits of explicitly defaulted and deleted functions. In C++, the compiler automatically generates the default constructor, copy constructor, copy-assignment operator, and destructor for a type if it doesn't declare its own. These functions are known as the special member functions, and they're what make simple user-defined types in C++ ...

  11. Copy Assignment Operator

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

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

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

  14. C++ Class and Preventing Object Copy · ariya.io

    C++ Class and Preventing Object Copy. Jan 10, 2015 4 min read #c++ #coding. In some cases, an instance of a C++ class should not be copied at all. There are three ways to prevent such an object copy: keeping the copy constructor and assignment operator private, using a special non-copyable mixin, or deleting those special member functions.. A class that represents a wrapper stream of a file ...

  15. OOP54-CPP. Gracefully handle self-copy assignment

    The copy assignment operator uses std::move() rather than swap() to achieve safe self-assignment and a strong exception guarantee. The move assignment operator uses a move (via the method parameter) and swap. The move constructor is not strictly necessary, but defining a move constructor along with a move assignment operator is conventional for classes that support move operations.

  16. How to prevent object copy in C++

    In this tutorial, we will learn how to prevent object copy in C++. This can be done in 3 ways and we shall implement each of these. Making the access specifier of Copy constructor and Copy assignment operator private

  17. Copy assignment operator

    the copy assignment operator selected for every non-static class type (or array of class type) member 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. Solved In C++ Complete the copy assignment operator to

    Computer Science. Computer Science questions and answers. In C++ Complete the copy assignment operator to prevent self-assignment. Ex: If the input is 1219.50, then the output is: Self-assignment not permitted userAccount: $1886.00 deposit amount copyAccount: $1219.50 deposit amount Destructor called Destructor.

  19. c++

    It is cricially important for assignment operator to work correctly, even when object is assigned to itself. A good way to do so is to copy the right-hand operand before destroying the left hand operand. the example in the book; class has one data member ps and ps is string *. C& operator=(const C &rhs) {. auto newp = new string(*rhs.ps)

  20. C++ Assignment Operator overloading unexpected behavior

    That is the returned temporary object created within your assignment operator is used to initialize the newly defined object C by means of the default copy constructor. Again the object B will be unchanged as pointed out above. One more the above code snippet is equivalent to. Point C = B.operator =( A );