- C Programming Tutorial
- C - Overview
- C - Features
- C - History
- C - Environment Setup
- C - Program Structure
- C - Hello World
- C - Compilation Process
- C - Comments
- C - Keywords
- C - Identifiers
- C - User Input
- C - Basic Syntax
- C - Data Types
- C - Variables
- C - Integer Promotions
- C - Type Conversion
- C - Constants
- C - Literals
- C - Escape sequences
- C - Format Specifiers
- C - Storage Classes
- C - Operators
- C - Decision Making
- C - While loop
- C - Functions
- C - Scope Rules
- C - Pointers
- C - Strings
- C - Structures
- C - Bit Fields
- C - Typedef
- C - Input & Output
- C - File I/O
- C - Preprocessors
- C - Header Files
- C - Type Casting
- C - Error Handling
- C - Recursion
- C - Variable Arguments
- C - Memory Management
- C - Command Line Arguments
- C Programming Resources
- C - Questions & Answers
- C - Quick Guide
- C - Useful Resources
- C - Discussion
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
Assignment Operators in C
In C, the assignment operator stores a certain value in an already declared variable. A variable in C can be assigned the value in the form of a literal, another variable or an expression. The value to be assigned forms the right hand operand, whereas the variable to be assigned should be the operand to the left of = symbol, which is defined as a simple assignment operator in C. In addition, C has several augmented assignment operators.
The following table lists the assignment operators supported by the C language −
Simple assignment operator (=)
The = operator is the most frequently used operator in C. As per ANSI C standard, all the variables must be declared in the beginning. Variable declaration after the first processing statement is not allowed. You can declare a variable to be assigned a value later in the code, or you can initialize it at the time of declaration.
You can use a literal, another variable or an expression in the assignment statement.
Once a variable of a certain type is declared, it cannot be assigned a value of any other type. In such a case the C compiler reports a type mismatch error.
In C, the expressions that refer to a memory location are called "lvalue" expressions. A lvalue may appear as either the left-hand or right-hand side of an assignment.
On the other hand, the term rvalue refers to a data value that is stored at some address in memory. A rvalue is an expression that cannot have a value assigned to it which means an rvalue may appear on the right-hand side but not on the left-hand side of an assignment.
Variables are lvalues and so they may appear on the left-hand side of an assignment. Numeric literals are rvalues and so they may not be assigned and cannot appear on the left-hand side. Take a look at the following valid and invalid statements −
Augmented assignment operators
In addition to the = operator, C allows you to combine arithmetic and bitwise operators with the = symbol to form augmented or compound assignment operator. The augmented operators offer a convenient shortcut for combining arithmetic or bitwise operation with assignment.
For example, the expression a+=b has the same effect of performing a+b first and then assigning the result back to the variable a.
Similarly, the expression a<<=b has the same effect of performing a<<b first and then assigning the result back to the variable a.
Here is a C program that demonstrates the use of assignment operators in C:
When you compile and execute the above program, it produces the following result −
- C++ Language
- Ascii Codes
- Boolean Operations
- Numerical Bases
Basics of c++.
- Structure of a program
- Variables and types
- Basic Input/Output
- Statements and flow control
- Overloads and templates
- Name visibility
Compound data types
- Character sequences
- Dynamic memory
- Data structures
- Other data types
- Classes (I)
- Classes (II)
- Special members
- Friendship and inheritance
Other language features
- Type conversions
- Preprocessor directives
- Input/output with files
Assignment operator (=)
Arithmetic operators ( +, -, *, /, % ), compound assignment (+=, -=, *=, /=, %=, >>=, <<=, &=, ^=, |=), increment and decrement (++, --), relational and comparison operators ( ==, =, >, <, >=, <= ), logical operators ( , &&, || ), conditional ternary operator ( ), comma operator ( , ), bitwise operators ( &, |, ^, ~, <<, >> ), explicit type casting operator, other operators, precedence of operators.
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Assignment operators (C# reference)
- 11 contributors
The assignment operator = assigns the value of its right-hand operand to a variable, a property , or an indexer element given by its left-hand operand. The result of an assignment expression is the value assigned to the left-hand operand. The type of the right-hand operand must be the same as the type of the left-hand operand or implicitly convertible to it.
The assignment operator = is right-associative, that is, an expression of the form
is evaluated as
The following example demonstrates the usage of the assignment operator with a local variable, a property, and an indexer element as its left-hand operand:
The left-hand operand of an assignment receives the value of the right-hand operand. When the operands are of value types , assignment copies the contents of the right-hand operand. When the operands are of reference types , assignment copies the reference to the object.
This is called value assignment : the value is assigned.
Ref assignment = ref makes its left-hand operand an alias to the right-hand operand, as the following example demonstrates:
In the preceding example, the local reference variable arrayElement is initialized as an alias to the first array element. Then, it's ref reassigned to refer to the last array element. As it's an alias, when you update its value with an ordinary assignment operator = , the corresponding array element is also updated.
The left-hand operand of ref assignment can be a local reference variable , a ref field , and a ref , out , or in method parameter. Both operands must be of the same type.
For a binary operator op , a compound assignment expression of the form
is equivalent to
except that x is only evaluated once.
Compound assignment is supported by arithmetic , Boolean logical , and bitwise logical and shift operators.
You can use the null-coalescing assignment operator ??= to assign the value of its right-hand operand to its left-hand operand only if the left-hand operand evaluates to null . For more information, see the ?? and ??= operators article.
A user-defined type can't overload the assignment operator. However, a user-defined type can define an implicit conversion to another type. That way, the value of a user-defined type can be assigned to a variable, a property, or an indexer element of another type. For more information, see User-defined conversion operators .
A user-defined type can't explicitly overload a compound assignment operator. However, if a user-defined type overloads a binary operator op , the op= operator, if it exists, is also implicitly overloaded.
C# language specification
For more information, see the Assignment operators section of the C# language specification .
- C# reference
- C# operators and expressions
- ref keyword
- Use compound assignment (style rules IDE0054 and IDE0074)
Submit and view feedback for
- Sign In / Suggest an Article
Current ISO C++ status
Upcoming ISO C++ meetings
Upcoming C++ conferences
Compiler conformance status
C++ (on Sea) Online
ISO C++ committee meeting
March 18-23, Tokyo, Japan
April 17-20, Bristol, UK
using std::cpp 2024
April 25-26, Leganes, Spain
C++ Now 2024
May 7-12, Aspen, CO, USA
June 24-29, St. Louis, MO, USA
July 2-5, Folkestone, Kent, UK
What is a reference?
An alias (an alternate name) for an object.
References are frequently used for pass-by-reference:
Here i and j are aliases for main’s x and y respectively. In other words, i is x — not a pointer to x , nor a copy of x , but x itself. Anything you do to i gets done to x , and vice versa. This includes taking the address of it. The values of &i and &x are identical.
That’s how you should think of references as a programmer. Now, at the risk of confusing you by giving you a different perspective, here’s how references are implemented. Underneath it all, a reference i to object x is typically the machine address of the object x . But when the programmer says i++ , the compiler generates code that increments x . In particular, the address bits that the compiler uses to find x are not changed. A C programmer will think of this as if you used the C style pass-by-pointer, with the syntactic variant of (1) moving the & from the caller into the callee, and (2) eliminating the * s. In other words, a C programmer will think of i as a macro for (*p) , where p is a pointer to x (e.g., the compiler automatically dereferences the underlying pointer; i++ is changed to (*p)++ ; i = 7 is automatically changed to *p = 7 ).
Important note: Even though a reference is often implemented using an address in the underlying assembly language, please do not think of a reference as a funny looking pointer to an object. A reference is the object, just with another name. It is neither a pointer to the object, nor a copy of the object. It is the object. There is no C++ syntax that lets you operate on the reference itself separate from the object to which it refers.
What happens if you assign to a reference?
You change the state of the referent (the referent is the object to which the reference refers).
Remember: the reference is the referent, so changing the reference changes the state of the referent. In compiler writer lingo, a reference is an “lvalue” (something that can appear on the left hand side of an assignment operator ).
What happens if you return a reference?
The function call can appear on the left hand side of an assignment operator .
This ability may seem strange at first. For example, no one thinks the expression f() = 7 makes sense. Yet, if a is an object of class Array , most people think that a[i] = 7 makes sense even though a[i] is really just a function call in disguise (it calls Array::operator(int) , which is the subscript operator for class Array ).
What does object.method1().method2() mean?
It chains these method calls, which is why this is called method chaining .
The first thing that gets executed is object.method1() . This returns some object, which might be a reference to object (i.e., method1() might end with return *this; ), or it might be some other object. Let’s call the returned object objectB . Then objectB becomes the this object of method2() .
The most common use of method chaining is in the iostream library. E.g., cout << x << y works because cout << x is a function that returns cout .
A less common, but still rather slick, use for method chaining is in the Named Parameter Idiom .
How can you reseat a reference to make it refer to a different object?
You can’t separate the reference from the referent.
Unlike a pointer, once a reference is bound to an object, it can not be “reseated” to another object. The reference isn’t a separate object. It has no identity. Taking the address of a reference gives you the address of the referent. Remember: the reference is its referent.
In that sense, a reference is similar to a const pointer such as int* const p (as opposed to a pointer to const such as const int* p ). But please don’t confuse references with pointers; they’re very different from the programmer’s standpoint.
Why does C++ have both pointers and references?
C++ inherited pointers from C, so they couldn’t be removed without causing serious compatibility problems. References are useful for several things, but the direct reason they were introduced in C++ was to support operator overloading. For example:
More generally, if you want to have both the functionality of pointers and the functionality of references, you need either two different types (as in C++) or two different sets of operations on a single type. For example, with a single type you need both an operation to assign to the object referred to and an operation to assign to the reference/pointer. This can be done using separate operators (as in Simula). For example:
Alternatively, you could rely on type checking (overloading). For example:
When should I use references, and when should I use pointers?
Use references when you can, and pointers when you have to.
References are usually preferred over pointers whenever you don’t need “reseating” . This usually means that references are most useful in a class’s public interface. References typically appear on the skin of an object, and pointers on the inside.
The exception to the above is where a function’s parameter or return value needs a “sentinel” reference — a reference that does not refer to an object. This is usually best done by returning/taking a pointer, and giving the nullptr value this special significance ( references must always alias objects, not a dereferenced null pointer ).
Note: Old line C programmers sometimes don’t like references since they provide reference semantics that isn’t explicit in the caller’s code. After some C++ experience, however, one quickly realizes this is a form of information hiding, which is an asset rather than a liability. E.g., programmers should write code in the language of the problem rather than the language of the machine.
What does it mean that a reference must refer to an object, not a dereferenced null pointer?
It means this is illegal:
NOTE: Please do not email us saying the above works on your particular version of your particular compiler. It’s still illegal. The C++ language, as defined by the C++ standard, says it’s illegal; that makes it illegal. The C++ standard does not require a diagnostic for this particular error, which means your particular compiler is not obliged to notice that p is nullptr or to give an error message, but it’s still illegal. The C++ language also does not require the compiler to generate code that would blow up at runtime. In fact, your particular version of your particular compiler may, or may not, generate code that you think makes sense if you do the above. But that’s the point: since the compiler is not required to generate sensible code, you don’t know what the compiler will do. So please do not email us saying your particular compiler generates good code; we don’t care. It’s still illegal. See the C++ standard for more, for example, C++ 2014 section 8.3.2 [dcl.ref] p5.
By way of example and not by way of limitation, some compilers do optimize nullptr tests since they “know” all references refer to real objects — that references are never (legally) a dereferenced nullptr . That can cause a compiler to optimize away the following test:
As stated above, this is just an example of the sort of thing your compiler might do based on the language rule that says a reference must refer to a valid object. Do not limit your thinking to the above example; the message of this FAQ is that the compiler is not required to do something sensible if you violate the rules. So don’t violate the rules.
Patient: “Doctor, doctor, my eye hurts when I poke it with a spoon.” Doctor: “Don’t poke it, then.”
What is a handle to an object? Is it a pointer? Is it a reference? Is it a pointer-to-a-pointer? What is it?
The term handle is used to mean any technique that lets you get to another object — a generalized pseudo-pointer. The term is (intentionally) ambiguous and vague.
Ambiguity is actually an asset in certain cases. For example, during early design you might not be ready to commit to a specific representation for the handles. You might not be sure whether you’ll want simple pointers vs. references vs. pointers-to-pointers vs. references-to-pointers vs. integer indices into an array vs. strings (or other key) that can be looked up in a hash-table (or other data structure) vs. database keys vs. some other technique. If you merely know that you’ll need some sort of thingy that will uniquely identify and get to an object, you call the thingy a Handle.
So if your ultimate goal is to enable a glop of code to uniquely identify/look-up a specific object of some class Fred , you need to pass a Fred handle into that glop of code. The handle might be a string that can be used as a key in some well-known lookup table (e.g., a key in a std::map<std::string,Fred> or a std::map<std::string,Fred*> ), or it might be an integer that would be an index into some well-known array (e.g., Fred* array = new Fred[maxNumFreds] ), or it might be a simple Fred* , or it might be something else.
Novices often think in terms of pointers, but in reality there are downside risks to using raw pointers. E.g., what if the Fred object needs to move? How do we know when it’s safe to delete the Fred objects? What if the Fred object needs to (temporarily) get serialized on disk? etc., etc. Most of the time we add more layers of indirection to manage situations like these. For example, the handles might be Fred** , where the pointed-to Fred* pointers are guaranteed to never move but when the Fred objects need to move, you just update the pointed-to Fred* pointers. Or you make the handle an integer then have the Fred objects (or pointers to the Fred objects) looked up in a table/array/whatever. Or whatever.
The point is that we use the word Handle when we don’t yet know the details of what we’re going to do.
Another time we use the word Handle is when we want to be vague about what we’ve already done (sometimes the term magic cookie is used for this as well, as in, “The software passes around a magic cookie that is used to uniquely identify and locate the appropriate Fred object”). The reason we (sometimes) want to be vague about what we’ve already done is to minimize the ripple effect if/when the specific details/representation of the handle change. E.g., if/when someone changes the handle from a string that is used in a lookup table to an integer that is looked up in an array, we don’t want to go and update a zillion lines of code.
To further ease maintenance if/when the details/representation of a handle changes (or to generally make the code easier to read/write), we often encapsulate the handle in a class. This class often overloads operators operator-> and operator* (since the handle acts like a pointer, it might as well look like a pointer).
Should I use call-by-value or call-by-reference?
(Note: This FAQ needs to be updated for C++11.)
That depends on what you are trying to achieve:
- If you want to change the object passed, call by reference or use a pointer; e.g., void f(X&); or void f(X*); .
- If you don’t want to change the object passed and it is big, call by const reference; e.g., void f(const X&); .
- Otherwise, call by value; e.g. void f(X); .
What does “big” mean? Anything larger than a couple of words.
Why would you want to change an argument? Well, often we have to, but often we have an alternative: produce a new value. Consider:
For a reader, incr2() is likely easier to understand. That is, incr1() is more likely to lead to mistakes and errors. So, we should prefer the style that returns a new value over the one that modifies a value as long as the creation and copy of a new value isn’t expensive.
What if you do want to change the argument, should you use a pointer or use a reference? If passing “not an object” (e.g., a null pointer) is acceptable, using a pointer makes sense. One style is to use a pointer when you want to modify an object because in some contexts that makes it easier to spot that a modification is possible.
Note also that a call of a member function is essentially a call-by-reference on the object, so we often use member functions when we want to modify the value/state of an object.
Why is this not a reference?
Because this was introduced into C++ (really into C with Classes) before references were added. Also, Stroustrup chose this to follow Simula usage, rather than the (later) Smalltalk use of self .
Please Login to submit a recommendation.
If you don’t have an account, you can register for free.
Assignment operators modify the value of the object.
copy assignment operator replaces the contents of the object a with a copy of the contents of b ( b is not modified). For class types, this is a special member function, described in copy assignment operator .
move assignment operator replaces the contents of the object a with the contents of b , avoiding copying if possible ( b may be modified). For class types, this is a special member function, described in move assignment operator . (since C++11)
For non-class types, copy and move assignment are indistinguishable and are referred to as direct assignment .
compound assignment operators replace the contents of the object a with the result of a binary operation between the previous value of a and the value of b .
Builtin direct assignment
The direct assignment expressions have the form
For the built-in operator, lhs may have any non-const scalar type and rhs must be implicitly convertible to the type of lhs .
The direct assignment operator expects a modifiable lvalue as its left operand and an rvalue expression or a braced-init-list (since C++11) as its right operand, and returns an lvalue identifying the left operand after modification.
For non-class types, the right operand is first implicitly converted to the cv-unqualified type of the left operand, and then its value is copied into the object identified by left operand.
When the left operand has reference type, the assignment operator modifies the referred-to object.
If the left and the right operands identify overlapping objects, the behavior is undefined (unless the overlap is exact and the type is the same)
In overload resolution against user-defined operators , for every type T , the following function signatures participate in overload resolution:
For every enumeration or pointer to member type T , optionally volatile-qualified, the following function signature participates in overload resolution:
For every pair A1 and A2, where A1 is an arithmetic type (optionally volatile-qualified) and A2 is a promoted arithmetic type, the following function signature participates in overload resolution:
Builtin compound assignment
The compound assignment expressions have the form
The behavior of every builtin compound-assignment expression E1 op = E2 (where E1 is a modifiable lvalue expression and E2 is an rvalue expression or a braced-init-list (since C++11) ) is exactly the same as the behavior of the expression E1 = E1 op E2 , except that the expression E1 is evaluated only once and that it behaves as a single operation with respect to indeterminately-sequenced function calls (e.g. in f ( a + = b, g ( ) ) , the += is either not started at all or is completed as seen from inside g ( ) ).
In overload resolution against user-defined operators , for every pair A1 and A2, where A1 is an arithmetic type (optionally volatile-qualified) and A2 is a promoted arithmetic type, the following function signatures participate in overload resolution:
For every pair I1 and I2, where I1 is an integral type (optionally volatile-qualified) and I2 is a promoted integral type, the following function signatures participate in overload resolution:
For every optionally cv-qualified object type T , the following function signatures participate in overload resolution:
- 90% Refund @Courses
- C++ Data Types
- C++ Pointers
C++ Interview Questions
- C++ Programs
- C++ Cheatsheet
- C++ Projects
C++ Exception Handling
- C++ Memory Management
- Solve Coding Problems
- C++ Programming Language
- Introduction to C++ Programming Language
- Features of C++
- History of C++
- Interesting Facts about C++
- Setting up C++ Development Environment
- Difference between C and C++
- Writing First C++ Program - Hello World Example
- C++ Basic Syntax
- C++ Comments
- Tokens in C
- C++ Keywords
- Difference between Keyword and Identifier
C++ Variables and Constants
- C++ Variables
- Constants in C
- Scope of Variables in C++
- Storage Classes in C++ with Examples
- Static Keyword in C++
C++ Data Types and Literals
- Literals in C
- Derived Data Types in C++
- User Defined Data Types in C++
- Data Type Ranges and their macros in C++
- C++ Type Modifiers
- Type Conversion in C++
- Casting Operators in C++
- Operators in C++
- C++ Arithmetic Operators
- Unary operators in C
- Bitwise Operators in C
- Assignment Operators in C
- C++ sizeof Operator
- Scope resolution operator in C++
- Basic Input / Output in C++
- cout in C++
- cerr - Standard Error Stream Object in C++
- Manipulators in C++ with Examples
C++ Control Statements
- Decision Making in C (if , if..else, Nested if, if-else-if )
- C++ if Statement
- C++ if else Statement
- C++ if else if Ladder
- Switch Statement in C++
- Jump statements in C++
- for Loop in C++
- Range-based for loop in C++
- C++ While Loop
- C++ Do/While Loop
- Functions in C++
- return statement in C++ with Examples
- Parameter Passing Techniques in C
- Difference Between Call by Value and Call by Reference in C
- Default Arguments in C++
- Inline Functions in C++
- Lambda expression in C++
C++ Pointers and References
- Pointers and References in C++
- Dangling, Void , Null and Wild Pointers in C
- Applications of Pointers in C
- Understanding nullptr in C++
References in C++
- Can References Refer to Invalid Location in C++?
- Pointers vs References in C++
- Passing By Pointer vs Passing By Reference in C++
- When do we pass arguments by pointer?
- Variable Length Arrays (VLAs) in C
- Pointer to an Array | Array Pointer
- How to print size of array parameter in C++?
- Pass Array to Functions in C
- What is Array Decay in C++? How can it be prevented?
- Strings in C++
- std::string class in C++
- Array of Strings in C++ - 5 Different Ways to Create
- String Concatenation in C++
- Tokenizing a string in C++
- Substring in C++
C++ Structures and Unions
- Structures, Unions and Enumerations in C++
- Structures in C++
- C++ - Pointer to Structure
- Self Referential Structures
- Difference Between C Structures and C++ Structures
- Enumeration in C++
- typedef in C++
- Array of Structures vs Array within a Structure in C
C++ Dynamic Memory Management
- Dynamic Memory Allocation in C using malloc(), calloc(), free() and realloc()
- new and delete Operators in C++ For Dynamic Memory
- new vs malloc() and free() vs delete in C++
- What is Memory Leak? How can we avoid?
- Difference between Static and Dynamic Memory Allocation in C
C++ Object-Oriented Programming
- Object Oriented Programming in C++
- C++ Classes and Objects
- Access Modifiers in C++
- Friend Class and Function in C++
- Constructors in C++
- Default Constructors in C++
- Copy Constructor in C++
- Destructors in C++
- Private Destructor in C++
- When is a Copy Constructor Called in C++?
- Shallow Copy and Deep Copy in C++
- When Should We Write Our Own Copy Constructor in C++?
- Does C++ compiler create default constructor when we write our own?
- C++ Static Data Members
- Static Member Function in C++
- 'this' pointer in C++
- Scope Resolution Operator vs this pointer in C++
- Local Classes in C++
- Nested Classes in C++
- Enum Classes in C++ and Their Advantage over Enum DataType
- Difference Between Structure and Class in C++
- Why C++ is partially Object Oriented Language?
C++ Encapsulation and Abstraction
- Encapsulation in C++
- Abstraction in C++
- Difference between Abstraction and Encapsulation in C++
- C++ Polymorphism
- Function Overriding in C++
- Virtual Functions and Runtime Polymorphism in C++
- Difference between Inheritance and Polymorphism
C++ Function Overloading
- Function Overloading in C++
- Constructor Overloading in C++
- Functions that cannot be overloaded in C++
- Function overloading and const keyword
- Function Overloading and Return Type in C++
- Function Overloading and float in C++
- C++ Function Overloading and Default Arguments
- Can main() be overloaded in C++?
- Function Overloading vs Function Overriding in C++
- Advantages and Disadvantages of Function Overloading in C++
C++ Operator Overloading
- Operator Overloading in C++
- Types of Operator Overloading in C++
- Functors in C++
- What are the Operators that Can be and Cannot be Overloaded in C++?
- Inheritance in C++
- C++ Inheritance Access
- Multiple Inheritance in C++
- C++ Hierarchical Inheritance
- C++ Multilevel Inheritance
- Constructor in Multiple Inheritance in C++
- Inheritance and Friendship in C++
- Does overloading work with Inheritance?
C++ Virtual Functions
- Virtual Function in C++
- Virtual Functions in Derived Classes in C++
- Default Arguments and Virtual Function in C++
- Can Virtual Functions be Inlined in C++?
- Virtual Destructor
- Advanced C++ | Virtual Constructor
- Advanced C++ | Virtual Copy Constructor
- Pure Virtual Functions and Abstract Classes in C++
- Pure Virtual Destructor in C++
- Can Static Functions Be Virtual in C++?
- RTTI (Run-Time Type Information) in C++
- Can Virtual Functions be Private in C++?
- Exception Handling in C++
- Exception Handling using classes in C++
- Stack Unwinding in C++
- User-defined Custom Exception with class in C++
C++ Files and Streams
- File Handling through C++ Classes
- I/O Redirection in C++
- Templates in C++ with Examples
- Template Specialization in C++
- Using Keyword in C++ STL
C++ Standard Template Library (STL)
- The C++ Standard Template Library (STL)
- Containers in C++ STL (Standard Template Library)
- Introduction to Iterators in C++
- Algorithm Library | C++ Magicians STL Algorithm
- C Preprocessors
- C Preprocessor Directives
- #include in C
- Difference between Preprocessor Directives and Function Templates in C++
- Namespace in C++ | Set 1 (Introduction)
- namespace in C++ | Set 2 (Extending namespace and Unnamed namespace)
- Namespace in C++ | Set 3 (Accessing, creating header, nesting and aliasing)
- C++ Inline Namespaces and Usage of the "using" Directive Inside Namespaces
- Multithreading in C++
- Smart Pointers in C++
- auto_ptr vs unique_ptr vs shared_ptr vs weak_ptr in C++
- Type of 'this' Pointer in C++
- "delete this" in C++
- Passing a Function as a Parameter in C++
- Signal Handling in C++
- Generics in C++
- Difference between C++ and Objective C
- Write a C program that won't compile in C++
- Write a program that produces different results in C and C++
- How does 'void*' differ in C and C++?
- Type Difference of Character Literals in C and C++
- Cin-Cout vs Scanf-Printf
C++ vs Java
- Similarities and Difference between Java and C++
- Comparison of Inheritance in C++ and Java
- How Does Default Virtual Behavior Differ in C++ and Java?
- Comparison of Exception Handling in C++ and Java
- Foreach in C++ and Java
- Templates in C++ vs Generics in Java
- Floating Point Operations & Associativity in C, C++ and Java
Competitive Programming in C++
- Competitive Programming - A Complete Guide
- C++ tricks for competitive programming (for C++ 11)
- Writing C/C++ code efficiently in Competitive programming
- Why C++ is best for Competitive Programming?
- Test Case Generation | Set 1 (Random Numbers, Arrays and Matrices)
- Fast I/O for Competitive Programming
- Setting up Sublime Text for C++ Competitive Programming Environment
- How to setup Competitive Programming in Visual Studio Code for C++
- Which C++ libraries are useful for competitive programming?
- Common mistakes to be avoided in Competitive Programming in C++ | Beginners
- Top 50 C++ Interview Questions and Answers (2024)
- Top C++ STL Interview Questions and Answers
- 30 OOPs Interview Questions and Answers (2024)
- Top C++ Exception Handling Interview Questions and Answers
- C++ Programming Examples
When a variable is declared as a reference, it becomes an alternative name for an existing variable. A variable can be declared as a reference by putting ‘&’ in the declaration.
Also, we can define a reference variable as a type of variable that can act as a reference to another variable. ‘&’ is used for signifying the address of a variable or any memory. Variables associated with reference variables can be accessed either by its name or by the reference variable associated with it.
Prerequisite: Pointers in C++
Applications of Reference in C++
There are multiple applications for references in C++, a few of them are mentioned below:
- Modify the passed parameters in a function
- Avoiding a copy of large structures
- In For Each Loop to modify all objects
- For Each Loop to avoid the copy of objects
1. Modify the passed parameters in a function :
If a function receives a reference to a variable, it can modify the value of the variable. For example, the following program variables are swapped using references.
2. Avoiding a copy of large structures :
Imagine a function that has to receive a large object. If we pass it without reference, a new copy of it is created which causes a waste of CPU time and memory. We can use references to avoid this.
3. In For Each Loop to modify all objects :
We can use references for each loop to modify all elements.
4. For Each Loop to avoid the copy of objects :
We can use references in each loop to avoid a copy of individual objects when objects are large.
References vs Pointers
Both references and pointers can be used to change the local variables of one function inside another function. Both of them can also be used to save copying of big objects when passed as arguments to functions or returned from functions, to get efficiency gain. Despite the above similarities, there are the following differences between references and pointers.
1. A pointer can be declared as void but a reference can never be void For example
2. The pointer variable has n-levels/multiple levels of indirection i.e. single-pointer, double-pointer, triple-pointer. Whereas, the reference variable has only one/single level of indirection. The following code reveals the mentioned points:
3. Reference variables cannot be updated.
4. Reference variable is an internal pointer.
5. Declaration of a Reference variable is preceded with the ‘&’ symbol ( but do not read it as “address of”).
Limitations of References
- Once a reference is created, it cannot be later made to reference another object; it cannot be reset. This is often done with pointers.
- References cannot be NULL. Pointers are often made NULL to indicate that they are not pointing to any valid thing.
- A reference must be initialized when declared. There is no such restriction with pointers.
Due to the above limitations, references in C++ cannot be used for implementing data structures like Linked List, Tree, etc. In Java, references don’t have the above restrictions and can be used to implement all data structures. References being more powerful in Java is the main reason Java doesn’t need pointers.
Advantages of using References
- Safer : Since references must be initialized, wild references like wild pointers are unlikely to exist. It is still possible to have references that don’t refer to a valid location (See questions 5 and 6 in the below exercise)
- Easier to use: References don’t need a dereferencing operator to access the value. They can be used like normal variables. The ‘&’ operator is needed only at the time of declaration. Also, members of an object reference can be accessed with the dot operator (‘.’), unlike pointers where the arrow operator (->) is needed to access members.
Together with the above reasons, there are a few places like the copy constructor argument where a pointer cannot be used. Reference must be used to pass the argument in the copy constructor. Similarly, references must be used for overloading some operators like ++.
Exercise with Answers
Question 1 :
- When do we pass arguments by reference or pointer?
- Can references refer to an invalid location in C++?
- Passing by pointer Vs Passing by Reference in C++
Whether you're preparing for your first job interview or aiming to upskill in this ever-evolving tech landscape, GeeksforGeeks Courses are your key to success. We provide top-quality content at affordable prices, all geared towards accelerating your growth in a time-bound manner. Join the millions we've already empowered, and we're here to do the same for you. Don't miss out - check it out now !
Looking for a place to share your ideas, learn, and connect? Our Community portal is just the spot! Come join us and see what all the buzz is about!
Please Login to comment...
- Top 12 AI Testing Tools for Test Automation in 2024
- 7 Best ChatGPT Plugins for Converting PDF to Editable Formats
- Microsoft is bringing Linux's Sudo command to Windows 11
- 10 Best AI Voice Cloning Tools to be Used in 2024 [Free + Paid]
- Dev Scripter 2024 - Biggest Technical Writing Event By GeeksforGeeks
Improve your Coding Skills with Practice
What kind of Experience do you want to share?
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 && .
- 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.
Customizes the C++ operators for operands of user-defined types.
[ edit ] Syntax
Overloaded operators are functions with special function names:
[ edit ] Overloaded operators
When an operator appears in an expression , and at least one of its operands has a class type or an enumeration type , then overload resolution is used to determine the user-defined function to be called among all the functions whose signatures match the following:
Note: for overloading co_await , (since C++20) user-defined conversion functions , user-defined literals , allocation and deallocation see their respective articles.
Overloaded operators (but not the built-in operators) can be called using function notation:
[ edit ] Restrictions
- The operators :: (scope resolution), . (member access), .* (member access through pointer to member), and ?: (ternary conditional) cannot be overloaded.
- New operators such as ** , <> , or &| cannot be created.
- It is not possible to change the precedence, grouping, or number of operands of operators.
- The overload of operator -> must either return a raw pointer, or return an object (by reference or by value) for which operator -> is in turn overloaded.
- The overloads of operators && and || lose short-circuit evaluation.
[ edit ] Canonical implementations
Besides the restrictions above, the language puts no other constraints on what the overloaded operators do, or on the return type (it does not participate in overload resolution), but in general, overloaded operators are expected to behave as similar as possible to the built-in operators: operator + is expected to add, rather than multiply its arguments, operator = is expected to assign, etc. The related operators are expected to behave similarly ( operator + and operator + = do the same addition-like operation). The return types are limited by the expressions in which the operator is expected to be used: for example, assignment operators return by reference to make it possible to write a = b = c = d , because the built-in operators allow that.
Commonly overloaded operators have the following typical, canonical forms: 
[ edit ] Assignment operator
The assignment operator ( operator = ) has special properties: see copy assignment and move assignment for details.
The canonical copy-assignment operator is expected to be safe on self-assignment , and to return the lhs by reference:
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 depending on the value category of the argument), swaps with the parameter, and lets the destructor clean it up.
This form automatically provides strong exception guarantee , but prohibits resource reuse.
[ edit ] Stream extraction and insertion
The overloads of operator>> and operator<< that take a std:: istream & or std:: ostream & as the left hand argument are known as insertion and extraction operators. Since they take the user-defined type as the right argument ( b in a @ b ), they must be implemented as non-members.
These operators are sometimes implemented as friend functions .
[ edit ] Function call operator
When a user-defined class overloads the function call operator, operator ( ) , it becomes a FunctionObject type.
An object of such a type can be used in a function call expression:
Many standard algorithms, from std:: sort to std:: accumulate accept FunctionObject s to customize behavior. There are no particularly notable canonical forms of operator ( ) , but to illustrate the usage:
[ edit ] Increment and decrement
When the postfix increment or decrement operator appears in an expression, the corresponding user-defined function ( operator ++ or operator -- ) is called with an integer argument 0 . Typically, it is implemented as T operator ++ ( int ) or T operator -- ( int ) , where the argument is ignored. The postfix increment and decrement operators are usually implemented in terms of the prefix versions:
Although the canonical implementations of the prefix increment and decrement operators return by reference, as with any operator overload, the return type is user-defined; for example the overloads of these operators for std::atomic return by value.
[ edit ] Binary arithmetic operators
Binary operators are typically implemented as non-members to maintain symmetry (for example, when adding a complex number and an integer, if operator+ is a member function of the complex type, then only complex + integer would compile, and not integer + complex ). Since for every binary arithmetic operator there exists a corresponding compound assignment operator, canonical forms of binary operators are implemented in terms of their compound assignments:
[ edit ] Comparison operators
Standard algorithms such as std:: sort and containers such as std:: set expect operator < to be defined, by default, for the user-provided types, and expect it to implement strict weak ordering (thus satisfying the Compare requirements). An idiomatic way to implement strict weak ordering for a structure is to use lexicographical comparison provided by std::tie :
Typically, once operator < is provided, the other relational operators are implemented in terms of operator < .
Likewise, the inequality operator is typically implemented in terms of operator == :
When three-way comparison (such as std::memcmp or std::string::compare ) is provided, all six two-way comparison operators may be expressed through that:
[ edit ] Array subscript operator
User-defined classes that provide array-like access that allows both reading and writing typically define two overloads for operator [ ] : const and non-const variants:
If the value type is known to be a scalar type, the const variant should return by value.
Where direct access to the elements of the container is not wanted or not possible or distinguishing between lvalue c [ i ] = v ; and rvalue v = c [ i ] ; usage, operator [ ] may return a proxy. See for example std::bitset::operator .
Because a subscript operator can only take one subscript until C++23, to provide multidimensional array access semantics, e.g. to implement a 3D array access a [ i ] [ j ] [ k ] = x ; , operator [ ] has to return a reference to a 2D plane, which has to have its own operator [ ] which returns a reference to a 1D row, which has to have operator [ ] which returns a reference to the element. To avoid this complexity, some libraries opt for overloading operator ( ) instead, so that 3D access expressions have the Fortran-like syntax a ( i, j, k ) = x ; .
[ edit ] Bitwise arithmetic operators
User-defined classes and enumerations that implement the requirements of BitmaskType are required to overload the bitwise arithmetic operators operator & , operator | , operator ^ , operator~ , operator & = , operator | = , and operator ^ = , and may optionally overload the shift operators operator << operator >> , operator >>= , and operator <<= . The canonical implementations usually follow the pattern for binary arithmetic operators described above.
[ edit ] Boolean negation operator
[ edit ] rarely overloaded operators.
The following operators are rarely overloaded:
- The address-of operator, operator & . If the unary & is applied to an lvalue of incomplete type and the complete type declares an overloaded operator & , it is unspecified whether the operator has the built-in meaning or the operator function is called. Because this operator may be overloaded, generic libraries use std::addressof to obtain addresses of objects of user-defined types. The best known example of a canonical overloaded operator& is the Microsoft class CComPtrBase . An example of this operator's use in EDSL can be found in boost.spirit .
- The boolean logic operators, operator && and operator || . Unlike the built-in versions, the overloads cannot implement short-circuit evaluation. Also unlike the built-in versions, they do not sequence their left operand before the right one. (until C++17) In the standard library, these operators are only overloaded for std::valarray .
- The comma operator, operator, . Unlike the built-in version, the overloads do not sequence their left operand before the right one. (until C++17) Because this operator may be overloaded, generic libraries use expressions such as a, void ( ) ,b instead of a,b to sequence execution of expressions of user-defined types. The boost library uses operator, in boost.assign , boost.spirit , and other libraries. The database access library SOCI also overloads operator, .
- The member access through pointer to member operator - > * . There are no specific downsides to overloading this operator, but it is rarely used in practice. It was suggested that it could be part of a smart pointer interface , and in fact is used in that capacity by actors in boost.phoenix . It is more common in EDSLs such as cpp.react .
[ edit ] Notes
[ edit ] example, [ edit ] defect reports.
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
[ edit ] See also
- Operator precedence
- Alternative operator syntax
- Argument-dependent lookup
[ 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 9 October 2023, at 05:12.
- This page has been accessed 5,317,006 times.
- About cppreference.com
- Manage your subscription
- Manage payment method
- Renew your subscription
Turn recurring billing on or off
- When subscription expires
- Cancel Microsoft 365
- Share Microsoft 365 Family
- Stop sharing Microsoft 365 Family
- You received an invitation to share
- Switch between Microsoft 365 subscriptions
- Switch to a business subscription
- Transfer to a different Microsoft account
- About accounts
- Sign in to Microsoft 365
- Why you need to sign in
- Forgot account or password
- Get started at Microsoft 365.com
- Meet the Microsoft 365 app launcher
- Check version
- Microsoft 365 for home or business
- What business product do I have?
- Difference between Microsoft 365 and Office 2021
- Difference between home and business plans
- Difference between Microsoft 365 and free web apps
- Can't install or manage Office or Microsoft 365
- Parental permission when signing in to Office or Microsoft 365
Manage your Microsoft 365 subscription or Office product
For most Microsoft 365 subscriptions and versions of Office (2013 and later), you need to associate an account with your product. This is the account you use to sign in to Microsoft365.com and what you use to install or reinstall the apps, or to manage your subscription. Depending on your product, this account can be a personal Microsoft account (such as Hotmail.com, Outlook.com, Live.com), or a work or school account assigned by someone in your organization.
Note: Some products purchased through an employee Microsoft Workplace Discount Program (formerly known as Home Use Program) benefit or volume license versions (managed by an organization's IT department) might not require an account. The information below doesn't apply to these Office versions or Microsoft 365 subscriptions.
Sign in to the dashboard for your account
Open a desktop app like Word or Excel, or go to Microsoft365.com .
Tip: You might be prompted to sign in. Make sure to sign in with the account associated with Microsoft 365 or Office. If you can’t remember which email address you associated with your subscription or Office product, see I can't remember the Microsoft account I use with Microsoft 365 .
From the header, select your Account manager .
Depending on your account type, select My Microsoft account or View account .
Your account dashboard is displayed and what you can do next depends on if you're signed in with a Microsoft account , or a work or school account .
Select the tab below for the type of account you're signed in with.
If you selected My Microsoft account , the Microsoft account dashboard will open. This is where you manage your Microsoft account and any Microsoft products associated with this account.
On the Microsoft account dashboard, select Services & subscriptions to view all Microsoft products associated with this account.
For non-subscription versions of Office (such as Office 2013 and later): Find your Office product and select Install . Follow the prompts to install or reinstall the desktop apps.
For Microsoft 365 Family or Personal subscriptions: Select Install premium Microsoft 365 apps and follow the prompts to install or reinstall the desktop apps.
On the Microsoft 365 subscription tab, select Manage . From here you can:
Renew your subscription with a prepaid code or card
Cancel a subscription
For Microsoft 365 Family subscriptions, you can start sharing your subscription, and add or remove people you're already sharing with. If you're not the subscription owner, you can see who's sharing Microsoft 365 with you, or choose to leave the subscription.
If you selected View account , the My Account dashboard for your work or school account will open. Here you can:
Install and manage your apps. On the Office apps card, select Manage , and select Install to install or reinstall the latest desktop apps, or other apps such as Project or Visio. (An install option is available as long as your admin assigned you a license and gave you permission to self-install.)
Manage your devices.
View your subscriptions, and any other licenses assigned to you.
Note: For Microsoft 365 admins only If you're the Microsoft 365 admin in your organization, you control what you want your users to have access to. Go to the Microsoft 365 Admin help center for more information about setting up users.
Need more help?
Want more options.
Explore subscription benefits, browse training courses, learn how to secure your device, and more.
Microsoft 365 subscription benefits
Microsoft 365 training
Communities help you ask and answer questions, give feedback, and hear from experts with rich knowledge.
Ask the Microsoft Community
Microsoft Tech Community
Microsoft 365 Insiders
Find solutions to common problems or get help from a support agent.
Was this information helpful?
Thank you for your feedback.