cppreference.com

Search

Assignment operators

Assignment operators modify the value of the object.

[ edit ] Explanation

basic assignment operator replaces the contents of the object a with those of b

move assignment operator replaces the contents of the object a with those of b while minimizing copying overhead (no deep copy is performed). It complements the basic assignment operator. (since C++11)

Other assignment operators modify the contents of the object. Usually they are overloaded in classes performing mathematical operations.

[ edit ] See also

Operator precedence

  • Recent changes
  • Offline version
  • What links here
  • Related changes
  • Upload file
  • Special pages
  • Printable version
  • Permanent link
  • This page was last modified on 15 June 2012, at 14:14.
  • This page has been accessed 1,039 times.
  • Privacy policy
  • About cppreference.com
  • Disclaimers

Powered by MediaWiki

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

  • Sign In / Suggest an Article

Current ISO C++ status

Upcoming ISO C++ meetings

Upcoming C++ conferences

Compiler conformance status

ISO C++ committee meeting

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

July 2-5, Folkestone, Kent, UK

assignment operators

Assignment operators, what is “self assignment”.

Self assignment is when someone assigns an object to itself. For example,

Obviously no one ever explicitly does a self assignment like the above, but since more than one pointer or reference can point to the same object (aliasing), it is possible to have self assignment without knowing it:

This is only valid for copy assignment. Self-assignment is not valid for move assignment.

Why should I worry about “self assignment”?

If you don’t worry about self assignment , you’ll expose your users to some very subtle bugs that have very subtle and often disastrous symptoms. For example, the following class will cause a complete disaster in the case of self-assignment:

If someone assigns a Fred object to itself, line #1 deletes both this->p_ and f.p_ since *this and f are the same object. But line #2 uses *f.p_ , which is no longer a valid object. This will likely cause a major disaster.

The bottom line is that you the author of class Fred are responsible to make sure self-assignment on a Fred object is innocuous . Do not assume that users won’t ever do that to your objects. It is your fault if your object crashes when it gets a self-assignment.

Aside: the above Fred::operator= (const Fred&) has a second problem: If an exception is thrown while evaluating new Wilma(*f.p_) (e.g., an out-of-memory exception or an exception in Wilma ’s copy constructor ), this->p_ will be a dangling pointer — it will point to memory that is no longer valid. This can be solved by allocating the new objects before deleting the old objects.

Okay, okay, already; I’ll handle self-assignment. How do I do it?

You should worry about self assignment every time you create a class . This does not mean that you need to add extra code to all your classes: as long as your objects gracefully handle self assignment, it doesn’t matter whether you had to add extra code or not.

We will illustrate the two cases using the assignment operator in the previous FAQ :

If self-assignment can be handled without any extra code, don’t add any extra code. But do add a comment so others will know that your assignment operator gracefully handles self-assignment:

Example 1a:

Example 1b:

If you need to add extra code to your assignment operator, here’s a simple and effective technique:

Or equivalently:

By the way: the goal is not to make self-assignment fast. If you don’t need to explicitly test for self-assignment, for example, if your code works correctly (even if slowly) in the case of self-assignment, then do not put an if test in your assignment operator just to make the self-assignment case fast. The reason is simple: self-assignment is almost always rare, so it merely needs to be correct - it does not need to be efficient. Adding the unnecessary if statement would make a rare case faster by adding an extra conditional-branch to the normal case, punishing the many to benefit the few.

In this case, however, you should add a comment at the top of your assignment operator indicating that the rest of the code makes self-assignment is benign, and that is why you didn’t explicitly test for it. That way future maintainers will know to make sure self-assignment stays benign, or if not, they will need to add the if test.

I’m creating a derived class; should my assignment operators call my base class’s assignment operators?

Yes (if you need to define assignment operators in the first place).

If you define your own assignment operators, the compiler will not automatically call your base class’s assignment operators for you. Unless your base class’s assignment operators themselves are broken, you should call them explicitly from your derived class’s assignment operators (again, assuming you create them in the first place).

However if you do not create your own assignment operators, the ones that the compiler create for you will automatically call your base class’s assignment operators.

Please Login to submit a recommendation.

If you don’t have an account, you can register for free.

Learn C++ practically and Get Certified .

Popular Tutorials

Popular examples, reference materials, learn c++ interactively, introduction to c++.

  • Getting Started With C++
  • Your First C++ Program
  • C++ Comments

C++ Fundamentals

  • C++ Keywords and Identifiers
  • C++ Variables, Literals and Constants
  • C++ Data Types
  • C++ Type Modifiers
  • C++ Constants
  • C++ Basic Input/Output
  • C++ Operators

Flow Control

  • C++ Relational and Logical Operators
  • C++ if, if...else and Nested if...else
  • C++ for Loop
  • C++ while and do...while Loop
  • C++ break Statement
  • C++ continue Statement
  • C++ goto Statement
  • C++ switch..case Statement
  • C++ Ternary Operator
  • C++ Functions
  • C++ Programming Default Arguments
  • C++ Function Overloading
  • C++ Inline Functions
  • C++ Recursion

Arrays and Strings

  • C++ Array to Function
  • C++ Multidimensional Arrays
  • C++ String Class

Pointers and References

  • C++ Pointers
  • C++ Pointers and Arrays
  • C++ References: Using Pointers
  • C++ Call by Reference: Using pointers
  • C++ Memory Management: new and delete

Structures and Enumerations

  • C++ Structures
  • C++ Structure and Function
  • C++ Pointers to Structure
  • C++ Enumeration

Object Oriented Programming

  • C++ Classes and Objects
  • C++ Constructors
  • C++ Constructor Overloading
  • C++ Destructors
  • C++ Access Modifiers
  • C++ Encapsulation
  • C++ friend Function and friend Classes

Inheritance & Polymorphism

  • C++ Inheritance
  • C++ Public, Protected and Private Inheritance
  • C++ Multiple, Multilevel and Hierarchical Inheritance
  • C++ Function Overriding
  • C++ Virtual Functions

C++ Abstract Class and Pure Virtual Function

STL - Vector, Queue & Stack

  • C++ Standard Template Library
  • C++ STL Containers
  • C++ std::array
  • C++ Vectors
  • C++ Forward List
  • C++ Priority Queue

STL - Map & Set

  • C++ Multimap
  • C++ Multiset
  • C++ Unordered Map
  • C++ Unordered Set
  • C++ Unordered Multiset
  • C++ Unordered Multimap

STL - Iterators & Algorithms

  • C++ Iterators
  • C++ Algorithm
  • C++ Functor

Additional Topics

  • C++ Exceptions Handling
  • C++ File Handling
  • C++ Ranged for Loop
  • C++ Nested Loop
  • C++ Function Template
  • C++ Class Templates
  • C++ Type Conversion
  • C++ Type Conversion Operators
  • C++ Operator Overloading

Advanced Topics

  • C++ Namespaces
  • C++ Preprocessors and Macros
  • C++ Storage Class
  • C++ Bitwise Operators
  • C++ Buffers
  • C++ istream
  • C++ ostream

C++ Tutorials

C++ Shadowing Base Class Member Function

C++ Polymorphism

C++ Multiple, Multilevel, Hierarchical and Virtual Inheritance

C++ Virtual Functions and Function Overriding

A virtual function is a member function in the base class that we expect to redefine in derived classes.

For example,

The print() method in the Derived class shadows the print() method in the Base class.

However, if we create a pointer of Base type to point to an object of Derived class and call the print() function, it calls the print() function of the Base class.

In other words, the member function of Base is not overridden.

To avoid this, we declare the print() function of the Base class as virtual by using the virtual keyword.

If the virtual function is redefined in the derived class, the function in the derived class is executed even if it is called using a pointer of the base class object pointing to a derived class object. In such a case, the function is said to be overridden.

Virtual functions are an integral part of polymorphism in C++. To learn more, check our tutorial on C++ Polymorphism .

  • Example 1: C++ virtual Function

Here, we have declared the print() method of Base as virtual .

So, this function is overridden even when we use a pointer of Base type that points to the Derived object derived1 .

C++ Working of Virtual Functions

  • C++ override Specifier

C++ 11 provides a new specifier override that is very useful to avoid common mistakes while using virtual functions.

This override specifier specifies the member functions of the derived classes that override the member function of the base class.

If we use a function prototype in Derived class and define that function outside of the class, then we use the following code:

Here, void print() override; is the function prototype in the Derived class. The override specifier ensures that the print() function in Base class is overridden by the print() function in Derived class.

If we use function prototype in Derived class, then we use override specifier in the function declaration only, not in the definition.

  • Use of C++ override

When using virtual functions, it is possible to make mistakes while declaring the member functions of the derived classes.

Using the override specifier prompts the compiler to display error messages when these mistakes are made.

Otherwise, the program will simply compile but the virtual function will not be overridden.

Some of these possible mistakes are:

  • Functions with incorrect names: For example, if the virtual function in the base class is named print() , but we accidentally name the overriding function in the derived class as pint() .
  • Functions with different return types: If the virtual function is, say, of void type but the function in the derived class is of int type.
  • Functions with different parameters: If the parameters of the virtual function and the functions in the derived classes don't match.
  • No virtual function is declared in the base class.
  • Virtual Destructor

When a derived class involves dynamic memory allocation, we have to deallocate the memory in its destructor.

When we delete shape1 which is a Square* pointing to a Square object, the destructor of the Square class is called, which deletes the dynamic memory acquired by the Square object.

However, if we delete shape2 which is a Shape* pointing to a Square object, the destructor of the Shape class is called, which doesn't deallocate the dynamic memory acquired by the Square object.

If we declare the Shape class destructor as virtual , the Square class destructor is called when we delete a pointer to Shape class pointing to a Square object.

  • Use of C++ Virtual Functions

Virtual functions are useful when we store a group of objects.

Suppose we have a base class Employee and derived classes HourlyEmployee and RegularEmployee . We can store Employee* pointers pointing to objects of both the derived classes in a collection of Employee* .

We can then call the virtual function using Employee* pointers. When we call the virtual function using Employee* pointers, the compiler invokes the function as defined in the respective derived class.

Here, the base class Employee has a virtual function print_wage() . The derived classes HourlyEmployee and RegularEmployee have their own implementation of the print_wage() function.

We have stored the Employee* pointers pointing to HourlyEmployee and RegularEmployee objects in a vector.

We then used ranged for loop to iterate through the pointers in the vector.

Here, employee->print_wage() invokes the print_wage() function based on the type of object that the pointer employee points to.

Table of Contents

  • Introduction

Sorry about that.

Related Tutorials

C++ Tutorial

Move assignment operator

A move 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 && , const T && , volatile T && , or const volatile T && .

Explanation

  • Typical declaration of a move assignment operator.
  • Forcing a move assignment operator to be generated by the compiler.
  • Avoiding implicit move assignment.

The move assignment operator is called whenever it is selected by overload resolution , e.g. when an object appears on the left-hand side of an assignment expression, where the right-hand side is an rvalue of the same or implicitly convertible type.

Move assignment operators typically "steal" the resources held by the argument (e.g. pointers to dynamically-allocated objects, file descriptors, TCP sockets, I/O streams, running threads, etc.), rather than make copies of them, and leave the argument in some valid but otherwise indeterminate state. For example, move-assigning from a std::string or from a std::vector may result in the argument being left empty. This is not, however, a guarantee. A move assignment is less, not more restrictively defined than ordinary assignment; where ordinary assignment must leave two copies of data at completion, move assignment is required to leave only one.

Implicitly-declared move assignment operator

If no user-defined move assignment operators are provided for a class type ( struct , class , or union ), and all of the following is true:

  • there are no user-declared copy constructors;
  • there are no user-declared move constructors;
  • there are no user-declared copy assignment operators;
  • there are no user-declared destructors;

then the compiler will declare a move assignment operator as an inline public member of its class with the signature T& T::operator=(T&&) .

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

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

Because some assignment operator (move or copy) 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 move assignment operator

The implicitly-declared or defaulted move assignment operator for class T is defined as deleted if 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 move-assigned (has deleted, inaccessible, or ambiguous move assignment operator);
  • T has direct or virtual base class that cannot be move-assigned (has deleted, inaccessible, or ambiguous move assignment operator);

Trivial move assignment operator

The move 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 move assignment operator selected for every direct base of T is trivial;
  • the move assignment operator selected for every non-static class type (or array of class type) member of T is trivial;

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

Implicitly-defined move assignment operator

If the implicitly-declared move 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 move assignment operator copies the object representation (as by std::memmove ).

For non-union class types ( class and struct ), the move assignment operator performs full member-wise move assignment of the object's direct bases and immediate non-static members, in their declaration order, using built-in assignment for the scalars, memberwise move-assignment for arrays, and move assignment operator for class types (called non-virtually).

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 move assignment operator (same applies to copy assignment ).

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

Move assignment operator

A move 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 && , const T && , volatile T && , or const volatile T && . A type with a public move assignment operator is MoveAssignable .

[ edit ] Syntax

[ edit ] explanation.

  • Typical declaration of a move assignment operator
  • Forcing a move assignment operator to be generated by the compiler
  • Avoiding implicit move assignment

The move assignment operator is called whenever it is selected by overload resolution , e.g. when an object appears on the left side of an assignment expression, where the right-hand side is an rvalue of the same or implicitly convertible type.

Move assignment operators typically "steal" the resources held by the argument (e.g. pointers to dynamically-allocated objects, file descriptors, TCP sockets, I/O streams, running threads, etc), rather than make copies of them, and leave the argument in some valid but otherwise indeterminate state. For example, move-assigning from a std:: string or from a std:: vector leaves the right-hand side argument empty.

[ edit ] Implicitly-declared move assignment operator

If no user-defined move assignment operators are provided for a class type ( struct , class , or union ), and all of the following is true:

  • there are no user-declared copy constructors
  • there are no user-declared move constructors
  • there are no user-declared copy assignment operators
  • there are no user-declared destructors
  • the implicitly-declared move assignment operator would not be defined as deleted

then the compiler will declare a move assignment operator as an inline public member of its class with the signature T& T::operator= T(T&&)

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

Because some assignment operator (move or copy) 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 move assignment operator

The implicitly-declared or defaulted move 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 move-assigned (has deleted, inaccessible, or ambiguous move assignment operator)
  • T has direct or virtual base class that cannot be move-assigned (has deleted, inaccessible, or ambiguous move assignment operator)
  • T has a non-static data member or a direct or virtual base without a move assignment operator that is not trivially copyable.
  • T has a direct or indirect virtual base class

[ edit ] Trivial move assignment operator

The implicitly-declared move 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 move assignment operator selected for every direct base of T is trivial
  • The move assignment operator selected for every non-static class type (or array of class type) memeber of T is trivial

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

[ edit ] Implicitly-defined move assignment operator

If the implicitly-declared move 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 move assignment operator copies the object representation (as by std:: memmove ). For non-union class types ( class and struct ), the move assignment operator performs full member-wise move assignment of the object's bases and non-static members, in their initialization order, using built-in assignment for the scalars and move assignment operator for class types.

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

The copy-and-swap assignment operator

T & T :: operator = ( T arg ) {     swap ( arg ) ;     return * this ; }

performs an equivalent of move assignment for rvalue arguments at the cost of one additional call to the move constructor of T, which is often acceptable.

[ edit ] Example

cpp virtual assignment operator

What’s New for C++ Developers in Visual Studio 2022 17.10

' data-src=

May 22nd, 2024 7 3

We are happy to announce that Visual Studio 2022 version 17.10 is now generally available! This post summarizes the new features you can find in this release for C++. You can download Visual Studio 2022 from the Visual Studio downloads page  or upgrade your existing installation by following the  Update Visual Studio Learn page .

Standard Library and Compiler

We have incremented the minor version number of the MSVC toolset from 19.39 (VS 2022 v17.9) to 19.40 (VS 2022 v17.10). For more details, and some ways in which this will affect projects that assume that MSVC versions are all 19.3X for Visual Studio 2022 releases, see the  MSVC Toolset Minor Version Number 14.40 in VS 2022 v17.10 blog post .

We’ve made a host of changes to our standard library implementation, with the help of the community. As always, you can see the STL Changelog for full details. We implemented C++26’s P2510R3 Formatting Pointers , which brings the set of format specifiers for pointers when using std::format more in line with those that already exist for integers. We also implemented a few smaller features from C++26 and C++23, such as P2836R1 , which makes std::basic_const_iterator act in a more natural way with respect to implicit conversions. On the performance side, we improved the vectorized implementations of std::min_element , std::ranges::min and friends, made the copy/move assignment operators of std::expected trivial when expected, and more.

C++ Productivity and Game Development

You can now use Build Insights to view your template instantiation information. Template instantiation collection must be activated in Tools > Options > Build Insights.

Recursive Template Instantiation

Check out our blog post on Templates View or our recording from Pure Virtual C++ for more details:

You can now keep our Unreal Engine plugin needed for Unreal Engine Test Adapter running in the background, greatly reducing startup costs. This is an opt-in feature that can be activated via Tools > Options > Unreal Engine. Furthermore, we have added additional Unreal Engine Macros to be indented in accordance with the UE Code Style.

Cross-Platform

If you’re targeting Linux, be sure to check out our video on our most recent development features for Linux from Pure Virtual C++:

CMake Targets View

We have added support for pinning CMake targets in the CMake Targets View. There is a top-level folder now for Pinned Targets. You can pin any targets by right-clicking and selecting the Pin option in the context menu.

Pinning a CMake Target via the context menu

You can also unpin any target in the Pinned Targets folder by selecting Unpin.

Connection Manager

We introduced some UX updates and usability improvements to the Connection Manager. With these updates we provide a more seamless experience when connecting to remote systems and/or debugging failed connections. Check out our blog post for more details.

Screenshot of the updated Connect to Remote System dialog with a failed connection error. The error is displayed above the fields in an info bar and the Host Name and Port field are highlighted and labelled as "may be incorrect". The Connect button is enabled.

Core Editor

View and address pull request comments.

You can now view your GitHub and Azure DevOps pull request comments directly in your working file in Visual Studio. Enable the feature flag, “Pull Request Comments,” in Options > Environment > Preview Features and checkout the pull request branch to get started.

A screen shot of a computer Description automatically generated

Generated Pull Request Descriptions

Similar to our generated  Git commit message feature , you can now get a first draft for your pull request description created by GitHub Copilot. You’ll need to verify you have an active GitHub Copilot subscription. Try it out by clicking the ‘Add AI Generated Pull Request Description’ sparkle pen icon within the Create a Pull Request window. Please share your feedback on this feature  here .

A screenshot of a computer Description automatically generated

Image Hover Preview

If you hover over the path to an image, Visual Studio will now give you a small preview of the image itself, along with the size of the image in pixels and bytes. The size is capped to 500px wide and high.

A screenshot of a computer Description automatically generated

New Text Formatting Options

You can now choose italic, bold, strikethrough, or underline styles for text formatting in the Options > Environment > Fonts and Colors settings:

A screenshot of a computer screen Description automatically generated

Creating Conditional Breakpoints and Tracepoints from Expressions

You can now create a conditional breakpoint or tracepoint directly from an expression in your source code from the right-click menu. This works on property or field names and values from autos, locals, watch windows, or DataTips:

cpp virtual assignment operator

Attach to Process Dialog Revamp

The Attach to Process dialog has been improved for better functionality and user-friendliness. You can now easily switch between tree and list views, organize processes better with collapsible sections, and select code types with a simplified combobox. Moreover, the “Select/Track Window” feature is now easier to use, allowing two-way tracking: selecting a process highlights its window, and clicking on a window selects its process.

cpp virtual assignment operator

GitHub Copilot

We have unified the experience from the GitHub Copilot and Copilot Chat extensions and shipped them directly in Visual Studio. To install it, install the GitHub Copilot component in the Visual Studio Installer:

Screenshot of the Visual Studio Installer. The GitHub Copilot component is highlighted with an orange outline.

To use it, you’ll need an active GitHub Copilot subscription, and you can find the interface in the top-right corner of Visual Studio.

Copilot in action

Send us your feedback

We are very much interested in your feedback to continue to improve this experience. The comments below are open. Feedback can also be shared through  Visual Studio Developer Community . You can also reach us on Twitter ( @VisualC ), or via email at  [email protected] .

' data-src=

Sy Brand C++ Developer Advocate, C++ Team

cpp virtual assignment operator

Leave a comment Cancel reply

Log in to join the discussion or edit/delete existing comments.

Very much appreciate the investments you’ve made in the native code tool chain in this release. I’d really like to see more of the same, particularly in the fields of: Code Analysis, scaling the solution for very large projects, local ML based navigational help for large code bases.

With the new version of the MSVC toolset, please consider documenting the behavior of the default value, and add a “latest” value to the corresponding project configuration: https://developercommunity.visualstudio.com/t/Default-value-of-MSVC-Toolset-is-not-doc/10398953

Hi Sy, i see that have been added an image hover preview, could you bring attention from the extension team about this feature request? Its been on “roadmap” for incontable years, almost 100 upvotes and a lot of comments requesting it 🙏🙏 Image Watch

I see there has been some work done on the debugger, but it would be nice if you could let your colleagues on the debugger team know that it is impossible to debug x86 C++ code in Visual Studio 2022 on Intel Sapphire Rapids Xeon CPUs in Windows 11 since August 2023 when those CPUs were released. I submitted a bug report , but it’s “under consideration” seemingly forever. Apparently nobody except me uses workstation class CPUs with Intel AMX instruction set extensions.

' data-src=

too long to wait for std::runtime_format. please update!

' data-src=

Honestly, it’s quite worrying that your FE team was fired. Have you had any luck hiring them back as 50% of your compiler doesn’t exist (and the other 50% from the BE generates worse code compared to competitors from a decade ago)

The lack of C++23 “language” features will soon be a blocker for my industry in particular. We have a set of “reference” guidance and the decision on whether we’re allowed to use C++23 will be made in what looks like a faster timeline then you’ll be able to put the compiler back together again…

Exciting update! But I think the build tools version increase unfortunately broke CUDA with CMake. I’ve submitted https://developercommunity.visualstudio.com/t/VS-2022-1710-C-build-tools-144019/10668943 .

light-theme-icon

Insert/edit link

Enter the destination URL

Or link to existing content

  • C++ Data Types
  • C++ Input/Output
  • C++ Pointers
  • C++ Interview Questions
  • C++ Programs
  • C++ Cheatsheet
  • C++ Projects
  • C++ Exception Handling
  • C++ Memory Management

Move Assignment Operator in C++ 11

  • Assignment Operators In C++
  • How to Implement Move Assignment Operator in C++?
  • Is assignment operator inherited?
  • JavaScript Assignment Operators
  • Self assignment check in assignment operator
  • Assignment Operators in Programming
  • Copy Constructor vs Assignment Operator in C++
  • How to Create Custom Assignment Operator in C++?
  • C++ Assignment Operator Overloading
  • Default Assignment Operator and References in C++
  • std::is_nothrow_move_assignable in C++
  • vector :: assign() in C++ STL
  • Solidity - Assignment Operators
  • basic_istream::operator>> in C++
  • bitset operator[] in C++ STL
  • Assignment Operators in C
  • Compound assignment operators in Java
  • Assignment Operators in Python
  • Java Assignment Operators with Examples

In C++ programming, we have a feature called the move assignment operator, which was introduced in C++11. It helps us handle objects more efficiently, especially when it comes to managing resources like memory. In this article, we will discuss move assignment operators, when they are useful and called, and how to create user-defined move assignment operators.

Move Assignment Operator

The move assignment operator was added in C++ 11 to further strengthen the move semantics in C++. It is like a copy assignment operator but instead of copying the data, this moves the ownership of the given data to the destination object without making any additional copies. The source object is left in a valid but unspecified state.

User-Defined Move Assignment Operator

The programmer can define the move assignment operator using the syntax given below:

As you may have noticed, the move assignment operator function uses a special && reference qualifier. It represents the r-value references (generally literals or temporary values).

Usually, it returns a reference to the object (in this case, *this) so you can chain assignments together.

The move constructor is called by the compiler when the argument is an rvalue reference which can be done by std::move() function. 

Example of Move Assignment Operator

In this program, we will create a dynamic array class and create a user-defined move assignment operator.

Explanation

The move assignment operator (operator=) is used to transfer resources from one DynamicArray object to another. It releases the current resources of the destination object, takes the resources from the source object, and leaves the source object in a valid but unspecified state.

In the main function:

  • We create two DynamicArray objects, arr1 with 5 elements and arr2 with 10 elements. We print their initial states.
  • We use the move assignment operator to transfer the resources from arr1 to arr2 by calling arr2 = std::move(arr1).
  • After the move, we print the states of both arr1 and arr2. arr1 is now in a valid but unspecified state, and arr2 contains the resources of arr1.
Note: We can also define a move constructor with a move assignment operator and reduce the code redundancy by calling the move assignment operator from the move constructor. To know about move constructor, refer to the article – Move Constructors in C++

Implicit Definition of Move Assignment Operator

The compiler also defines a default move assignment operator implicitly when the following conditions are satisfied:

  • No user-defined copy constructor is present.
  • No user-defined destructor is present.
  • No user-defined move constructor is present.

Need of Move Assignment Operator

In C++, objects can manage resources like memory. When we copy an object, it can be quite slow, especially if the object holds a lot of resources. Traditional copy operations create new copies, which can lead to unnecessary memory usage and slow down your program.

This is where move assignment operators come to the rescue. They let one object take over the resources of another, without making extra copies. This can significantly boost performance in scenarios like resizing arrays or returning objects from functions.

In contrast to the copy assignment operator, the end result of the move assignment operator will be a single copy of the source object.

Please Login to comment...

Similar reads.

  • Geeks Premier League 2023
  • Geeks Premier League

Improve your Coding Skills with Practice

 alt=

What kind of Experience do you want to share?

COMMENTS

  1. virtual assignment operator C++

    The assignment operator is not required to be made virtual. The discussion below is about operator=, but it also applies to any operator overloading that takes in the type in question, and any function that takes in the type in question.. The below discussion shows that the virtual keyword does not know about a parameter's inheritance in regards to finding a matching function signature.

  2. Assignment operators

    Variants. Assignment operators. Assignment operators modify the value of the object. All built-in assignment operators return *this, and most user-defined overloads also return *this so that the user-defined operators can be used in the same manner as the built-ins. However, in a user-defined operator overload, any type can be used as return ...

  3. c++

    1. Virtual assignment is an ungood idea because it introduces run time type-checking, moving bug detection etc. to run-time with more extensive and unreliable testing. - Cheers and hth. - Alf. Jul 15, 2015 at 7:25. I you want to see Calling B message you should try this virtual B& operator=(const A& b_) override { std::cout << "Calling B ...

  4. 25.4

    virtual ~Base() = default; // generate a virtual default destructor. Virtual assignment. It is possible to make the assignment operator virtual. However, unlike the destructor case where virtualization is always a good idea, virtualizing the assignment operator really opens up a bag full of worms and gets into some advanced topics outside of ...

  5. operator overloading

    In those situations where copy assignment cannot benefit from resource reuse (it does not manage a heap-allocated array and does not have a (possibly transitive) member that does, such as a member std::vector or std::string), there is a popular convenient shorthand: the copy-and-swap assignment operator, which takes its parameter by value (thus working as both copy- and move-assignment ...

  6. virtual function specifier

    Moreover, if the destructor of the base class is not virtual, deleting a derived class object through a pointer to the base class is undefined behavior regardless of whether there are resources that would be leaked if the derived destructor is not invoked, unless the selected deallocation function is a destroying operator delete (since C++20).. A useful guideline is that the destructor of any ...

  7. Assignment operators

    Assignment operators. From cppreference.com < cpp | language ... copy assignment: move assignment (C++11) destructor: Templates class template :

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

  9. Assignment Operators In C++

    In C++, the addition assignment operator (+=) combines the addition operation with the variable assignment allowing you to increment the value of variable by a specified expression in a concise and efficient way. Syntax. variable += value; This above expression is equivalent to the expression: variable = variable + value; Example.

  10. Assignment Operators

    If self-assignment can be handled without any extra code, don't add any extra code. But do add a comment so others will know that your assignment operator gracefully handles self-assignment: Example 1a: Fred& Fred::operator= (const Fred& f) {. // This gracefully handles self assignment. *p_ = *f.p_; return *this;

  11. C++ Virtual Functions and Function Overriding

    C++ 11 provides a new specifier override that is very useful to avoid common mistakes while using virtual functions. This override specifier specifies the member functions of the derived classes that override the member function of the base class. For example, class Base { public: virtual void print() {. // code.

  12. Virtual Function in C++

    Virtual Function in C++. A virtual function (also known as virtual methods) is a member function that is declared within a base class and is re-defined (overridden) by a derived class. When you refer to a derived class object using a pointer or a reference to the base class, you can call a virtual function for that object and execute the ...

  13. Assignment operators

    Assignment performs implicit conversion from the value of rhs to the type of lhs and then replaces the value in the object designated by lhs with the converted value of rhs . Assignment also returns the same value as what was stored in lhs (so that expressions such as a = b = c are possible). The value category of the assignment operator is non ...

  14. C++ Assignment Operator Overloading

    The assignment operator,"=", is the operator used for Assignment. It copies the right value into the left value. Assignment Operators are predefined to operate only on built-in Data types. Assignment operator overloading is binary operator overloading. Overloading assignment operator in C++ copies all values of one object to another object.

  15. Taligent's Guide to Designing Programs

    TDerived& TDerived::operator=(const TDerived &d) { TBase::operator=(d); } Always supply an assignment operator in such cases, because the default version C++ supplies will surely do the wrong thing: in addition to calling the base class operator, it will copy all your data members. On the other hand, if a class is going to be used in situations ...

  16. Move assignment operator

    then the compiler will declare a move assignment operator as an inline public member of its class with the signature T& T::operator=(T&&). A class can have multiple move assignment operators, e.g. both T& T::operator=(const T&&) and T& T::operator=(T&&). If some user-defined move assignment operators are present, the user may still force the ...

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

  18. Move assignment operator

    Forcing a move assignment operator to be generated by the compiler. Avoiding implicit move assignment. The move assignment operator is called whenever it is selected by overload resolution, e.g. when an object appears on the left side of an assignment expression, where the right-hand side is an rvalue of the same or implicitly convertible type.

  19. c++

    Well, you have no choice. s& operator =(const s& m) {. return *new(this) s(m); } Undefined behaviour. There's a reason why pretty much nobody uses const member variables, and it's because of this. There's nothing you can do about it. const member variables simply cannot be used in types you want to be assignable.

  20. Move assignment operator

    The move assignment operator is called whenever it is selected by overload resolution, e.g. when an object appears on the left-hand side of an assignment expression, where the right-hand side is an rvalue of the same or implicitly convertible type.. Move assignment operators typically "steal" the resources held by the argument (e.g. pointers to dynamically-allocated objects, file descriptors ...

  21. What's New for C++ Developers in Visual Studio 2022 17.10

    On the performance side, we improved the vectorized implementations of std::min_element, std::ranges::min and friends, made the copy/move assignment operators of std::expected trivial when expected, and more. C++ Productivity and Game Development. You can now use Build Insights to view your template instantiation information.

  22. Move Assignment Operator in C++ 11

    The move assignment operator was added in C++ 11 to further strengthen the move semantics in C++. It is like a copy assignment operator but instead of copying the data, this moves the ownership of the given data to the destination object without making any additional copies. The source object is left in a valid but unspecified state.