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.

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)

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

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.

DR Applied to Behavior as published Correct behavior
C++14 operator=(X&) = default was non-trivial made trivial

Navigation Menu

Search code, repositories, users, issues, pull requests..., provide feedback.

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly.

To see all available qualifiers, see our documentation .

  • Notifications You must be signed in to change notification settings

copy-constructors-and-copy-assignment-operators-cpp.md

Latest commit, file metadata and controls.

description title ms.date helpviewer_keywords ms.assetid

Copy constructors and copy assignment operators (C++)

Starting in C++11, two kinds of assignment are supported in the language: copy assignment and move assignment . In this article "assignment" means copy assignment unless explicitly stated otherwise. For information about move assignment, see Move Constructors and Move Assignment Operators (C++) .

Both the assignment operation and the initialization operation cause objects to be copied.

Assignment : When one object's value is assigned to another object, the first object is copied to the second object. 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 .

22.3 — Move constructors and move assignment

Copy assignment operator

(C++11)
(C++11)
(C++11)
General
Members
pointer
initializer(C++11)
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 & . A type with a public copy assignment operator is CopyAssignable .

Syntax Explanation Implicitly-declared copy assignment operator Deleted implicitly-declared copy assignment operator Trivial copy assignment operator Implicitly-defined copy assignment operator Notes Copy and swap Example

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

C++ At Work

Copy Constructors, Assignment Operators, and More

Paul DiLascia

Code download available at: CAtWork0509.exe (276 KB) Browse the Code Online

Q I have a simple C++ problem. I want my copy constructor and assignment operator to do the same thing. Can you tell me the best way to accomplish this?

A At first glance this seems like a simple question with a simple answer: just write a copy constructor that calls operator=.

Or, alternatively, write a common copy method and call it from both your copy constructor and operator=, like so:

This code works fine for many classes, but there's more here than meets the eye. In particular, what happens if your class contains instances of other classes as members? To find out, I wrote the test program in Figure 1 . It has a main class, CMainClass, which contains an instance of another class, CMember. Both classes have a copy constructor and assignment operator, with the copy constructor for CMainClass calling operator= as in the first snippet. The code is sprinkled with printf statements to show which methods are called when. To exercise the constructors, cctest first creates an instance of CMainClass using the default ctor, then creates another instance using the copy constructor:

Figure 1 Copy Constructors and Assignment Operators

If you compile and run cctest, you'll see the following printf messages when cctest constructs obj2:

The member object m_obj got initialized twice! First by the default constructor, and again via assignment. Hey, what's going on?

In C++, assignment and copy construction are different because the copy constructor initializes uninitialized memory, whereas assignment starts with an existing initialized object. If your class contains instances of other classes as data members, the copy constructor must first construct these data members before it calls operator=. The result is that these members get initialized twice, as cctest shows. Got it? It's the same thing that happens with the default constructor when you initialize members using assignment instead of initializers. For example:

As opposed to:

Using assignment, m_obj is initialized twice; with the initializer syntax, only once. So, what's the solution to avoid extra initializations during copy construction? While it goes against your instinct to reuse code, this is one situation where it's best to implement your copy constructor and assignment operator separately, even if they do the same thing. Calling operator= from your copy constructor will certainly work, but it's not the most efficient implementation. My observation about initializers suggests a better way:

Now the main copy ctor calls the member object's copy ctor using an initializer, and m_obj is initialized just once by its copy ctor. In general, copy ctors should invoke the copy ctors of their members. Likewise for assignment. And, I may as well add, the same goes for base classes: your derived copy ctor and assignment operators should invoke the corresponding base class methods. Of course, there are always times when you may want to do something different because you know how your code works—but what I've described are the general rules, which are to be broken only when you have a compelling reason. If you have common tasks to perform after the basic objects have been initialized, you can put them in a common initialization method and call it from your constructors and operator=.

Q Can you tell me how to call a Visual C++® class from C#, and what syntax I need to use for this?

Sunil Peddi

Q I have an application that is written in both C# (the GUI) and in classic C++ (some business logic). Now I need to call from a DLL written in C++ a function (or a method) in a DLL written in Visual C++ .NET. This one calls another DLL written in C#. The Visual C++ .NET DLL acts like a proxy. Is this possible? I was able to use LoadLibrary to call a function present in the Visual C++ .NET DLL, and I can receive a return value, but when I try to pass some parameters to the function in the Visual C++ .NET DLL, I get the following error:

How can I resolve this problem?

Giuseppe Dattilo

A I get a lot of questions about interoperability between the Microsoft® .NET Framework and native C++, so I don't mind revisiting this well-covered topic yet again. There are two directions you can go: calling the Framework from C++ or calling C++ from the Framework. I won't go into COM interop here as that's a separate issue best saved for another day.

Let's start with the easiest one first: calling the Framework from C++. The simplest and easiest way to call the Framework from your C++ program is to use the Managed Extensions. These Microsoft-specific C++ language extensions are designed to make calling the Framework as easy as including a couple of files and then using the classes as if they were written in C++. Here's a very simple C++ program that calls the Framework's Console class:

To use the Managed Extensions, all you need to do is import <mscorlib.dll> and whatever .NET assemblies contain the classes you plan to use. Don't forget to compile with /clr:

Your C++ code can use managed classes more or less as if they were ordinary C++ classes. For example, you can create Framework objects with operator new, and access them using C++ pointer syntax, as shown in the following:

Here, the String s is declared as pointer-to-String because String::Format returns a new String object.

The "Hello, world" and date/time programs seem childishly simple—and they are—but just remember that however complex your program is, however many .NET assemblies and classes you use, the basic idea is the same: use <mscorlib.dll> and whatever other assemblies you need, then create managed objects with new, and use pointer syntax to access them.

So much for calling the Framework from C++. What about going the other way, calling C++ from the Framework? Here the road forks into two options, depending on whether you want to call extern C functions or C++ class member functions. Again, I'll take the simpler case first: calling C functions from .NET. The easiest thing to do here is use P/Invoke. With P/Invoke, you declare the external functions as static methods of a class, using the DllImport attribute to specify that the function lives in an external DLL. In C# it looks like this:

This tells the compiler that MessageBox is a function in user32.dll that takes an IntPtr (HWND), two Strings, and an int. You can then call it from your C# program like so:

Of course, you don't need P/Invoke for MessageBox since the .NET Framework already has a MessageBox class, but there are plenty of API functions that aren't supported directly by the Framework, and then you need P/Invoke. And, of course, you can use P/Invoke to call C functions in your own DLLs. I've used C# in the example, but P/Invoke works with any .NET-based language like Visual Basic® .NET or JScript®.NET. The names are the same, only the syntax is different.

Note that I used IntPtr to declare the HWND. I could have got away with int, but you should always use IntPtr for any kind of handle such as HWND, HANDLE, or HDC. IntPtr will default to 32 or 64 bits depending on the platform, so you never have to worry about the size of the handle.

DllImport has various modifiers you can use to specify details about the imported function. In this example, CharSet=CharSet.Auto tells the Framework to pass Strings as Unicode or Ansi, depending on the target operating system. Another little-known modifier you can use is CallingConvention. Recall that in C, there are different calling conventions, which are the rules that specify how the compiler should pass arguments and return values from one function to another across the stack. The default CallingConvention for DllImport is CallingConvention.Winapi. This is actually a pseudo-convention that uses the default convention for the target platform; for example, StdCall (in which the callee cleans the stack) on Windows® platforms and CDecl (in which the caller cleans the stack) on Windows CE .NET. CDecl is also used with varargs functions like printf.

The calling convention is where Giuseppe ran into trouble. C++ uses yet a third calling convention: thiscall. With this convention, the compiler uses the hardware register ECX to pass the "this" pointer to class member functions that don't have variable arguments. Without knowing the exact details of Giuseppe's program, it sounds from the error message that he's trying to call a C++ member function that expects thiscall from a C# program that's using StdCall—oops!

Aside from calling conventions, another interoperability issue when calling C++ methods from the Framework is linkage: C and C++ use different forms of linkage because C++ requires name-mangling to support function overloading. That's why you have to use extern "C" when you declare C functions in C++ programs: so the compiler won't mangle the name. In Windows, the entire windows.h file (now winuser.h) is enclosed in extern "C" brackets.

While there may be a way to call C++ member functions in a DLL directly using P/Invoke and DllImport with the exact mangled names and CallingConvention=ThisCall, it's not something to attempt if you're in your right mind. The proper way to call C++ classes from managed code—option number two—is to wrap your C++ classes in managed wrappers. Wrapping can be tedious if you have lots of classes, but it's really the only way to go. Say you have a C++ class CWidget and you want to wrap it so .NET clients can use it. The basic formula looks something like this:

The pattern is the same for any class. You write a managed (__gc) class that holds a pointer to the native class, you write a constructor and destructor that allocate and destroy the instance, and you write wrapper methods that call the corresponding native C++ member functions. You don't have to wrap all the member functions, only the ones you want to expose to the managed world.

Figure 2 shows a simple but concrete example in full detail. CPerson is a class that holds the name of a person, with member functions GetName and SetName to change the name. Figure 3 shows the managed wrapper for CPerson. In the example, I converted Get/SetName to a property, so .NET-based programmers can use the property syntax. In C#, using it looks like this:

Figure 3 Managed Person Class

Figure 2 Native CPerson Class

Using properties is purely a matter of style; I could equally well have exposed two methods, GetName and SetName, as in the native class. But properties feel more like .NET. The wrapper class is an assembly like any other, but one that links with the native DLL. This is one of the cool benefits of the Managed Extensions: You can link directly with native C/C++ code. If you download and compile the source for my CPerson example, you'll see that the makefile generates two separate DLLs: person.dll implements a normal native DLL and mperson.dll is the managed assembly that wraps it. There are also two test programs: testcpp.exe, a native C++ program that calls the native person.dll and testcs.exe, which is written in C# and calls the managed wrapper mperson.dll (which in turn calls the native person.dll).

Figure 4** Interop Highway **

I've used a very simple example to highlight the fact that there are fundamentally only a few main highways across the border between the managed and native worlds (see Figure 4 ). If your C++ classes are at all complex, the biggest interop problem you'll encounter is converting parameters between native and managed types, a process called marshaling. The Managed Extensions do an admirable job of making this as painless as possible (for example, automatically converting primitive types and Strings), but there are times where you have to know something about what you're doing.

For example, you can't pass the address of a managed object or subobject to a native function without pinning it first. That's because managed objects live in the managed heap, which the garbage collector is free to rearrange. If the garbage collector moves an object, it can update all the managed references to that object—but it knows nothing of raw native pointers that live outside the managed world. That's what __pin is for; it tells the garbage collector: don't move this object. For strings, the Framework has a special function PtrToStringChars that returns a pinned pointer to the native characters. (Incidentally, for those curious-minded souls, PtrToStringChars is the only function as of this date defined in <vcclr.h>. Figure 5 shows the code.) I used PtrToStringChars in MPerson to set the Name (see Figure 3 ).

Figure 5 PtrToStringChars

Pinning isn't the only interop problem you'll encounter. Other problems arise if you have to deal with arrays, references, structs, and callbacks, or access a subobject within an object. This is where some of the more advanced techniques come in, such as StructLayout, boxing, __value types, and so on. You also need special code to handle exceptions (native or managed) and callbacks/delegates. But don't let these interop details obscure the big picture. First decide which way you're calling (from managed to native or the other way around), and if you're calling from managed to native, whether to use P/Invoke or a wrapper.

In Visual Studio® 2005 (which some of you may already have as beta bits), the Managed Extensions have been renamed and upgraded to something called C++/CLI. Think of the C++/CLI as Managed Extensions Version 2, or What the Managed Extensions Should Have Been. The changes are mostly a matter of syntax, though there are some important semantic changes, too. In general C++/CLI is designed to highlight rather than blur the distinction between managed and native objects. Using pointer syntax for managed objects was a clever and elegant idea, but in the end perhaps a little too clever because it obscures important differences between managed and native objects. C++/CLI introduces the key notion of handles for managed objects, so instead of using C pointer syntax for managed objects, the CLI uses ^ (hat):

As you no doubt noticed, there's also a gcnew operator to clarify when you're allocating objects on the managed heap as opposed to the native one. This has the added benefit that gcnew doesn't collide with C++ new, which can be overloaded or even redefined as a macro. C++/CLI has many other cool features designed to make interoperability as straightforward and intuitive as possible.

Send your questions and comments for Paul to   [email protected] .

Paul DiLascia is a freelance software consultant and Web/UI designer-at-large. He is the author of Windows ++: Writing Reusable Windows Code in C ++ (Addison-Wesley, 1992). In his spare time, Paul develops PixieLib, an MFC class library available from his Web site, www.dilascia.com .

Additional resources

  • C Data Types
  • C Operators
  • C Input and Output
  • C Control Flow
  • C Functions
  • C Preprocessors
  • C File Handling
  • C Cheatsheet
  • C Interview Questions

Assignment Operators in C

implement copy assignment operator in c

Assignment operators are used for assigning value to a variable. The left side operand of the assignment operator is a variable and right side operand of the assignment operator is a value. The value on the right side must be of the same data-type of the variable on the left side otherwise the compiler will raise an error.

Different types of assignment operators are shown below:

1. “=”: This is the simplest assignment operator. This operator is used to assign the value on the right to the variable on the left. Example:

2. “+=” : This operator is combination of ‘+’ and ‘=’ operators. This operator first adds the current value of the variable on left to the value on the right and then assigns the result to the variable on the left. Example:

If initially value stored in a is 5. Then (a += 6) = 11.

3. “-=” This operator is combination of ‘-‘ and ‘=’ operators. This operator first subtracts the value on the right from the current value of the variable on left and then assigns the result to the variable on the left. Example:

If initially value stored in a is 8. Then (a -= 6) = 2.

4. “*=” This operator is combination of ‘*’ and ‘=’ operators. This operator first multiplies the current value of the variable on left to the value on the right and then assigns the result to the variable on the left. Example:

If initially value stored in a is 5. Then (a *= 6) = 30.

5. “/=” This operator is combination of ‘/’ and ‘=’ operators. This operator first divides the current value of the variable on left by the value on the right and then assigns the result to the variable on the left. Example:

If initially value stored in a is 6. Then (a /= 2) = 3.

Below example illustrates the various Assignment Operators:

Please Login to comment...

Similar reads.

  • C-Operators
  • cpp-operator
  • Best External Hard Drives for Mac in 2024: Top Picks for MacBook Pro, MacBook Air & More
  • How to Watch NFL Games Live Streams Free
  • OpenAI o1 AI Model Launched: Explore o1-Preview, o1-Mini, Pricing & Comparison
  • How to Merge Cells in Google Sheets: Step by Step Guide
  • #geekstreak2024 – 21 Days POTD Challenge Powered By Deutsche Bank

Improve your Coding Skills with Practice

 alt=

What kind of Experience do you want to share?

cppreference.com

The rule of three/five/zero.

(C++20)
(C++20)
(C++11)
(C++20)
(C++17)
(C++11)
(C++11)
General topics
(C++11)
-
-expression
block


/
(C++11)
(C++11)
(C++11)
(C++20)
(C++20)
(C++11)

expression
pointer
specifier

specifier (C++11)
specifier (C++11)
(C++11)

(C++11)
(C++11)
(C++11)
Rule of three Rule of five Rule of zero External links

[ edit ] Rule of three

If a class requires a user-defined destructor , a user-defined copy constructor , or a user-defined copy assignment operator , it almost certainly requires all three.

Because C++ copies and copy-assigns objects of user-defined types in various situations (passing/returning by value, manipulating a container, etc), these special member functions will be called, if accessible, and if they are not user-defined, they are implicitly-defined by the compiler.

The implicitly-defined special member functions should not be used if the class manages a resource whose handle does not destroy the resource themselves (raw pointer, POSIX file descriptor, etc), whose destructor does nothing and copy constructor/assignment operator only copies the value of the handle, without duplicating the underlying resource.

Classes that manage non-copyable resources through copyable handles may have to declare copy assignment and copy constructor private and not provide their definitions (until C++11) define copy assignment and copy constructor as = delete (since C++11) . This is another application of the rule of three: deleting one and leaving the other to be implicitly-defined typically incorrect.

[ edit ] Rule of five

Because the presence of a user-defined (include = default or = delete declared) destructor, copy-constructor, or copy-assignment operator prevents implicit definition of the move constructor and the move assignment operator , any class for which move semantics are desirable, has to declare all five special member functions:

Unlike Rule of Three, failing to provide move constructor and move assignment is usually not an error, but it will result in a loss of performance.

[ edit ] Rule of zero

Classes that have custom destructors, copy/move constructors or copy/move assignment operators should deal exclusively with ownership (which follows from the Single Responsibility Principle ). Other classes should not have custom destructors, copy/move constructors or copy/move assignment operators [1] .

This rule also appears in the C++ Core Guidelines as C.20: If you can avoid defining default operations, do .

When a base class is intended for polymorphic use, its destructor may have to be declared public and virtual . This blocks implicit moves (and deprecates implicit copies), and so the special member functions have to be defined as = default [2] .

However, this makes the class prone to slicing, which is why polymorphic classes often define copy as = delete (see C.67: A polymorphic class should suppress public copy/move in C++ Core Guidelines), which leads to the following generic wording for the Rule of Five:

[ edit ] External links

.
  • 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 2 September 2024, at 07:04.
  • Privacy policy
  • About cppreference.com
  • Disclaimers

Powered by MediaWiki

  • ▼C Programming
  • Overview of C
  • Compile and execute C program in Linux and Windows
  • C Variables and Constants
  • C Data Types
  • C Operators
  • C while loop
  • C do while loop
  • C Functions
  • C Recursion
  • C Command-Line Arguments
  • C Memory Allocation
  • C File Handling
  • C Preprocessor Directives
  • C Error Handling
  • C Typedef and Enum
  • C Multithreading
  • C Bitwise Operators
  • C Pointers and Functions
  • C Arrays and Pointers
  • C Structures
  • C Library ctype
  • C Library math
  • C Library string
  • C Library stdio
  • C Library stdlib
  • C Library time

Understanding Bitwise Operators with examples in C

Introduction to bitwise operators.

Bitwise operators allow direct manipulation of individual bits within data. They are crucial for systems programming, hardware interfacing, and performance optimizations. In this tutorial, we will explore bitwise operations such as AND, OR, XOR, NOT, bit shifting, and how to use bit masks through examples.

Key Topics:

  • AND (&) operator
  • OR (|) operator

XOR (^) operator

NOT (~) operator

Left Shift (<<) operator

  • Right Shift (>>) operator

Using Bit Masks

AND (&) Operator:

Performs a bitwise AND operation. Each bit is compared, and the result is 1 only if both corresponding bits are 1.

When to Use:

  • When you need to check if certain bits are set (i.e., both bits are 1).
  • Used in creating bit masks for clearing specific bits or verifying flags.

Why to Use:

  • Useful for checking or isolating specific bits in bit-level manipulations, such as checking hardware status bits or enabling/disabling specific features.

The bitwise AND compares two numbers bit by bit, and the result is 1 only if both corresponding bits are 1.

Explanation:

  • 5 in binary: 0101
  • 3 in binary: 0011
  • 5 & 3: 0001 (Only the last bit is 1 in both numbers).

OR (|) Operator:

Performs a bitwise OR operation. Each bit is compared, and the result is 1 if either of the corresponding bits is 1.

  • To set particular bits to 1 in a number without changing other bits.
  • Useful for setting specific flags or combining multiple conditions.
  • Handy when you want to enable a specific feature or setting by manipulating individual bits.

The bitwise OR operation results in 1 when either of the bits in the two numbers is 1.

  • 5 | 3: 0111 (If either bit is 1, the result is 1).

Performs a bitwise XOR operation. Each bit is compared, and the result is 1 only if the corresponding bits differ.

  • To toggle bits between 0 and 1.
  • Can be used to swap two variables without a temporary variable.
  • Useful for flipping specific bits, performing parity checks, or detecting bitwise changes.

Bitwise XOR compares two numbers bit by bit, and the result is 1 if the bits differ.

  • 5 ^ 3: 0110 (If the bits are different, the result is 1).

Inverts all the bits in a number. Each 0 becomes 1 and each 1 becomes 0.

  • To reverse all the bits in a number.
  • Often used to apply bit-level negation in bit masks or perform two’s complement operations.
  • Useful when you want to invert bit values, especially for creating masks or flipping specific bits.

The bitwise NOT operator inverts all the bits in a number, converting 0s to 1s and vice versa.

  • 5 in binary: 00000000 00000000 00000000 00000101
  • ~5 in binary: 11111111 11111111 11111111 11111010 (Flipping each bit).
  • The result is -6 due to two's complement representation for negative numbers.

Shifts the bits of a number to the left by a specified number of positions, filling the new bits with 0.

  • To multiply a number by powers of 2.
  • Commonly used in embedded systems and low-level programming to pack or align data efficiently.
  • Improves efficiency when multiplying by 2^n, as it avoids costly multiplication operations.

Left shifting shifts bits to the left by a specified number of positions, effectively multiplying the number by 2 for each shift.

  • Shifting 5 (binary 0101) left by one position gives 1010, which is 10 in decimal.

Right Shift (>>) operator

Shifts the bits of a number to the right by a specified number of positions. The new leftmost bits depend on the number's sign (0 for unsigned, sign-extended for signed).

  • To divide a number by powers of 2.
  • Commonly used to extract parts of packed data.
  • Provides a fast way to divide numbers by powers of 2, especially in performance-sensitive code.

Right shifting shifts bits to the right by a specified number of positions, effectively dividing the number by 2 for each shift.

  • Shifting 5 (binary 0101) right by one position gives 0010, which is 2 in decimal.

A bit mask is a pattern of bits used to select or manipulate specific bits in a number.

  • To isolate, set, or clear specific bits in a number.
  • Frequently used in hardware programming, protocol design, and situations where specific flags or features are controlled by individual bits.
  • Bit masks provide a precise way to manipulate data at the bit level, allowing you to work with specific bits without affecting others. They are essential in managing flags, permissions, or configuration settings in low-level programming.

Bit masks are used to isolate or manipulate specific bits within a number, often using the AND operation to clear or retain specific bits.

  • The binary number 1101 is masked with 0100, and the result is 0100 which is 4 in decimal.

Follow us on Facebook and Twitter for latest update.

It will be nice if you may share this link in any developer community or anywhere else, from where other developers may find this content. Thanks.

https://www.w3resource.com/c-programming/c-bitwise-operators.php

  • Weekly Trends and Language Statistics
  • 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.

Implement C++ assignment operator in terms of constructor

Suppose you want to implement a resource-managing class in C++. You cannot use the Rule of Zero or Rule of Five Defaults , so you actually need to implement copy and move constructor, copy and move assignment operator, and destructor. In this question, Iʼll use Box as an example, but this can apply to lots of different types.

(Note that a better Box implementation would have more features like noexcept and constexpr functions, explicit forwarding constructors based on value_type ʼs constructors, allocator support, etc; here Iʼm implementing just whatʼs necessary for the question and the tests. It might also save some code with std::unique_ptr , but that would make it a less-clear example)

Note that the assignment operators share lots of code with each other, with their respective constructors, and with the destructor. This would be somewhat lessened if I didnʼt want to allow assignment to moved-from Box en, but would be more apparent in a more complicated class.

Digression: Copy-and-Swap

One standard way of handling this is with the Copy-And-Swap Idiom (also in this context called the Rule of Four and a Half) , which also gets you a strong exception guarantee if swap is nothrow :

This allows you to write only one assignment operator (taking other by value lets the compiler move the other to the parameter if possible, and does the copying for you if necessary), and that assignment operator is simple (assuming you already have swap ). However, as the linked article says, that has issues such as doing an extra allocation and keeping extra copies of the contents around during the operation.

What I havenʼt seen before is something Iʼll call a Destroy-and-Initialize assignment operator. Since weʼre already doing all the work in the constructor, and an assigned-to version of the object should be identical to a copy-constructed one, why not use the constructor, as follows:

This still does an extra allocation like Copy-and-Swap does, but only in the copy assignment case instead of the move assignment case, and it does it after destroying one of the copies of T , so it doesnʼt fail under resource constraints.

  • Has this been proposed before, and if so where can I read more about it?
  • Is this UB in some cases, such as if the Box is a subobject of something else, or is it allowed to destroy and re-construct subobjects?
  • Does this have any downsides I havenʼt mentioned, like not being constexpr compatible?
  • Are there other options to avoid assignment operator code reuse, like this and the Rule of Four and a Half, when you canʼt just = default them?
  • copy-and-swap
  • rule-of-zero
  • rule-of-five

Daniel H's user avatar

  • 2 This approach will have UB if any of the non-static member of the class are const qualified or of a reference type: stackoverflow.com/a/58415092/4342498 –  NathanOliver Commented Nov 30, 2021 at 21:55
  • @NathanOliver Yeah, but nothing else would work either , unless you want to special-case the handling of that member and it makes sense to have that not change on assignment. –  Daniel H Commented Nov 30, 2021 at 22:34
  • That approach will cause invalid object if copy constructor throws. –  Phil1970 Commented Dec 1, 2021 at 0:18
  • @Phil1970 Ah, youʼre right, and at least in my example Box thereʼs no way to avoid it without just specifying that it requires T be nothrow copy constructible, which isnʼt otherwise required. And even then since the copy constructor is allocating memory, that might fail. It could work for move assignment in this case, which avoids some of the code reuse but not as much. –  Daniel H Commented Dec 1, 2021 at 0:47
  • I think that Copy and swap is adequate 99% of the time. The extra copy (when required) make the assignment transactional which is generally a good thing. If you really need more control, you can always write the operator yourself. –  Phil1970 Commented Dec 2, 2021 at 1:54

Know someone who can answer? Share a link to this question via email , Twitter , or Facebook .

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 .

Browse other questions tagged c++ copy-and-swap rule-of-zero rule-of-five or ask your own question .

  • The Overflow Blog
  • Looking under the hood at the tech stack that powers multimodal AI
  • Featured on Meta
  • Join Stack Overflow’s CEO and me for the first Stack IRL Community Event in...
  • User activation: Learnings and opportunities
  • What does a new user need in a homepage experience on Stack Overflow?
  • Announcing the new Staging Ground Reviewer Stats Widget

Hot Network Questions

  • Wondering about ancient methods of estimating the relative planetary distances
  • PCB design references and roadmap
  • Fundamental Sampling Theorem
  • How to react to a rejection based on a single one-line negative review?
  • How to win a teaching award?
  • My one-liner 'delete old files' command finds the right files but will not delete them
  • Was the total glaciation of the world, a.k.a. snowball earth, due to Bok space clouds?
  • Film about a girl who discovers she is from a family of magicians
  • Analytic continuation gives a covering space (and not just a local homeomorphism)
  • How can I prove that this expression defines the area of the quadrilateral?
  • Cheapest / Most efficient way for a human Wizard to not age?
  • string quartet + chamber orchestra + symphonic orchestra. Why?
  • Play the Final Fantasy Prelude
  • What's the origin and first meanings of the term "grand piano"?
  • Why Doesn't the cooling system on a rocket engine burn the fuel?
  • Is it possible to make sand from bones ? Would it have the same properties as regular sand?
  • Can a 20A circuit mix 15A and 20A receptacles, when a 20A is intended for occassional space heater use?
  • When is due diligence enough when attempting to contact a copyright holder?
  • Why are no metals green or blue?
  • meaning of a sentence from Agatha Christie (Murder of Roger Ackroyd)
  • Is there a way to hide/show seams on model?
  • How to plausibly delay the creation of the telescope
  • Numerical integration of ODEs: Why does higher accuracy and precision not lead to convergence?
  • Model looks dented but geometry is correct

implement copy assignment operator in c

IMAGES

  1. Assignment Operators in C

    implement copy assignment operator in c

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

    implement copy assignment operator in c

  3. Assignment Operators in C Example

    implement copy assignment operator in c

  4. Solved Using C++: How am I supposed to implement the copy

    implement copy assignment operator in c

  5. Assignment Operator in C Programming

    implement copy assignment operator in c

  6. C++ : copy and swap technique uses copy constructor inside assignment

    implement copy assignment operator in c

VIDEO

  1. assignment Operator C Language in Telugu

  2. Augmented assignment operators in C

  3. Assignment Operator in C Programming

  4. Assignment Operator Overloading In C++

  5. Assignment Operator│C programming│Part# 15│Learn CSE Malayalam

  6. Operators in C language

COMMENTS

  1. Copy assignment operator

    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.

  2. c++

    The copy constructor is for creating a new object. It copies an existing object to a newly constructed object.The copy constructor is used to initialize a new instance from an old instance. It is not necessarily called when passing variables by value into functions or as return values out of functions. The assignment operator is to deal with an ...

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

  4. 21.12

    21.12 — Overloading the assignment operator. Alex July 22, 2024. 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.

  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. If you don't declare a copy constructor, the compiler generates a member-wise copy constructor for you.

  6. PDF Copy Constructors and Assignment Operators

    assignment operators. While C++ will automatically provide these functions if you don't explicitly define them, in some cases you'll need to manually control how your objects are duplicated. This handout discusses copy constructors and assignment operators, including both high-level concepts and practical implementation techniques. Assignment ...

  7. Copy assignment operator

    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)

  8. Shallow Copy and Deep Copy in C++

    Shallow Copy and Deep Copy in C++. In general, creating a copy of an object means to create an exact replica of the object having the same literal value, data type, and resources. There are two ways that are used by C++ compiler to create a copy of objects. // Default assignment operator. Depending upon the resources like dynamic memory held by ...

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

  10. copy-constructors-and-copy-assignment-operators-cpp.md

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

  11. 22.3

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

  12. Implementing the copy constructor in terms of operator=

    Typically, the copy assignment operator will do some cleanup. If your class has a pointer to dynamically allocated memory, the first thing the copy-assignment operator should do is free that memory. This implementation of the copy constructor would give the copy assignment operator a dangling pointer, which you don't want to delete. -

  13. Copy assignment operators (C++ only)

    Copy assignment operators (C++ only) The copy assignment operator lets you create a new object from an existing one by initialization. A copy assignment operator of a class A is a nonstatic non-template member function that has one of the following forms: If you do not declare a copy assignment operator for a class A, the compiler will ...

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

  15. C++ at Work: Copy Constructors, Assignment Operators, and More

    In C++, assignment and copy construction are different because the copy constructor initializes uninitialized memory, whereas assignment starts with an existing initialized object. If your class contains instances of other classes as data members, the copy constructor must first construct these data members before it calls operator=.

  16. Assignment Operators in C

    1. "=": This is the simplest assignment operator. This operator is used to assign the value on the right to the variable on the left. Example: a = 10;b = 20;ch = 'y'; 2. "+=": This operator is combination of '+' and '=' operators. This operator first adds the current value of the variable on left to the value on the right and ...

  17. PDF Copy Constructors and Assignment Operators

    Unless you specify otherwise, C++ will automatically provide objects a basic copy constructor and assignment operator that simply invoke the copy constructors and assignment operators of all the class's data members. In many cases, this is exactly what you want. For example, consider the following class: class MyClass {public: /* Omitted ...

  18. The rule of three/five/zero

    Rule of three. If a class requires a user-defined destructor, a user-defined copy constructor, or a user-defined copy assignment operator, it almost certainly requires all three.. Because C++ copies and copy-assigns objects of user-defined types in various situations (passing/returning by value, manipulating a container, etc), these special member functions will be called, if accessible, and ...

  19. c++

    TestClass& operator=(const TestClass& Other); (you don't want to invoke the copy constructor for assignment, too) and it returns a reference to *this. A naive implementation would assign each data member individually: TestClass& operator=(const TestClass& Other) {. ClassName = Other.ClassName; return *this;

  20. Bitwise Operators in C: AND, OR, XOR, Shifting, and Bit Masks

    Bitwise operators allow direct manipulation of individual bits within data. They are crucial for systems programming, hardware interfacing, and performance optimizations. In this tutorial, we will explore bitwise operations such as AND, OR, XOR, NOT, bit shifting, and how to use bit masks through examples.

  21. c++

    Some developers used to actually implement assignment by in-place destruction followed by placement copy-construction. However, this is a very bad idea. (What if this is the assignment operator of a base class that called during assignment of a derived class?) What's usually considered the canonical idiom nowadays is using swap as Charles ...

  22. copy and swap

    You cannot use the Rule of Zero or Rule of Five Defaults, so you actually need to implement copy and move constructor, copy and move assignment operator, and destructor. In this question, Iʼll use Box as an example, but this can apply to lots of different types. using value_type = T; // Default constructor. Box() : elem{new value_type} {}