Call Assignment Operator Of Base Class Library

The latest version of this topic can be found at Assignment Operators.

Syntax

Assignment operators store a value in the object designated by the left operand. There are two kinds of assignment operations: simple assignment, in which the value of the second operand is stored in the object specified by the first operand, and compound assignment, in which an arithmetic, shift, or bitwise operation is performed prior to storing the result. All assignment operators in the following table except the = operator are compound assignment operators.

Assignment Operators

OperatorMeaning
=Store the value of the second operand in the object specified by the first operand (simple assignment).
*=Multiply the value of the first operand by the value of the second operand; store the result in the object specified by the first operand.
Divide the value of the first operand by the value of the second operand; store the result in the object specified by the first operand.
Take modulus of the first operand specified by the value of the second operand; store the result in the object specified by the first operand.
Add the value of the second operand to the value of the first operand; store the result in the object specified by the first operand.
–=Subtract the value of the second operand from the value of the first operand; store the result in the object specified by the first operand.
<<=Shift the value of the first operand left the number of bits specified by the value of the second operand; store the result in the object specified by the first operand.
>>=Shift the value of the first operand right the number of bits specified by the value of the second operand; store the result in the object specified by the first operand.
&=Obtain the bitwise AND of the first and second operands; store the result in the object specified by the first operand.
Obtain the bitwise exclusive OR of the first and second operands; store the result in the object specified by the first operand.
Obtain the bitwise inclusive OR of the first and second operands; store the result in the object specified by the first operand.

Operator Keywords

Three of the compound assignment operators have text equivalents. They are:

OperatorEquivalent
&=

There are two ways to access these operator keywords in your programs: include the header file , or compile with the /Za (Disable language extensions) compiler option.

The simple assignment operator (=) causes the value of the second operand to be stored in the object specified by the first operand. If both objects are of arithmetic types, the right operand is converted to the type of the left, prior to storing the value.

Objects of const and volatile types can be assigned to l-values of types that are just volatile or that are neither const nor volatile.

Assignment to objects of class type (struct, union, and class types) is performed by a function named operator=. The default behavior of this operator function is to perform a bitwise copy; however, this behavior can be modified using overloaded operators. (See Overloaded Operators for more information.)

An object of any unambiguously derived class from a given base class can be assigned to an object of the base class. The reverse is not true because there is an implicit conversion from derived class to base class but not from base class to derived class. For example:

Assignments to reference types behave as if the assignment were being made to the object to which the reference points.

For class-type objects, assignment is different from initialization. To illustrate how different assignment and initialization can be, consider the code

The preceding code shows an initializer; it calls the constructor for that takes an argument of type . Given the code

the assignment statement

can have one of the following effects:

  • Call the function operator= for , provided operator= is provided with a argument.

  • Call the explicit conversion function , if such a function exists.

  • Call a constructor , provided such a constructor exists, that takes a argument and copies the result.

The compound assignment operators, shown in the table in Assignment Operators, are specified in the form e1= e2, where e1 is a modifiable l-value not of const type and e2 is one of the following:

  • An arithmetic type

  • A pointer, if is + or –

The e1= e2 form behaves as e1= e1e2, but e1 is evaluated only once.

Compound assignment to an enumerated type generates an error message. If the left operand is of a pointer type, the right operand must be of a pointer type or it must be a constant expression that evaluates to 0. If the left operand is of an integral type, the right operand must not be of a pointer type.

The assignment operators return the value of the object specified by the left operand after the assignment. The resultant type is the type of the left operand. The result of an assignment expression is always an l-value. These operators have right-to-left associativity. The left operand must be a modifiable l-value.

In ANSI C, the result of an assignment expression is not an l-value. Therefore, the legal C++ expression is illegal in C.

Expressions with Binary Operators
C++ Operators
C++ Built-in Operators, Precedence and Associativity
C Assignment Operators

expression assignment-operator expression assignment-operator : one of = *= /= %= += –= <<= >>= &= ^= |=
// expre_Assignment_Operators.cpp // compile with: /EHsc // Demonstrate assignment operators #include <iostream> using namespace std; int main() { int a = 3, b = 6, c = 10, d = 0xAAAA, e = 0x5555; a += b; // a is 9 b %= a; // b is 6 c >>= 1; // c is 5 d |= e; // Bitwise--d is 0xFFFF cout << "a = 3, b = 6, c = 10, d = 0xAAAA, e = 0x5555" << endl << "a += b yields " << a << endl << "b %= a yields " << b << endl << "c >>= 1 yields " << c << endl << "d |= e yields " << hex << d << endl; }
// expre_SimpleAssignment.cpp // compile with: /EHsc #include <iostream> using namespace std; class ABase { public: ABase() { cout << "constructing ABase\n"; } }; class ADerived : public ABase { public: ADerived() { cout << "constructing ADerived\n"; } }; int main() { ABase aBase; ADerived aDerived; aBase = aDerived; // OK aDerived = aBase; // C2679 }
UserType1 A; UserType2 B = A;
UserType1 A; UserType2 B; B = A;

A copy assignment operator of class is a non-template non-static member function with the name operator= that takes exactly one parameter of type T, T&, const T&, volatile T&, or constvolatile T&. A type with a public copy assignment operator is .

[edit]Syntax

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

[edit]Explanation

  1. Typical declaration of a copy assignment operator when copy-and-swap idiom can be used
  2. Typical declaration of a copy assignment operator when copy-and-swap idiom cannot be used
  3. Forcing a copy assignment operator to be generated by the compiler
  4. Avoiding implicit copy assignment

The copy assignment operator is called whenever selected by overload resolution, e.g. when an object appears on the left side of an assignment expression.

[edit]Implicitly-declared copy assignment operator

If no user-defined copy assignment operators are provided for a class type (struct, class, or union), the compiler will always declare one as an inline public member of the class. This implicitly-declared copy assignment operator has the form T& T::operator=(const T&) if all of the following is true:

  • each direct base of has a copy assignment operator whose parameters are or or constvolatile B&
  • each non-static data member of of class type or array of class type has a copy assignment operator whose parameters are or or constvolatile M&

Otherwise the implicitly-declared copy assignment operator is declared as T& T::operator=(T&). (Note that due to these rules, the implicitly-declared copy assignment operator cannot bind to a volatile lvalue argument)

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

Because the copy assignment operator is always declared for any class, the base class assignment operator is always hidden. If a using-declaration is used to bring in the assignment operator from the base class, and its argument type could be the same as the argument type of the implicit assignment operator of the derived class, the using-declaration is also hidden by the implicit declaration.

[edit]Deleted implicitly-declared copy assignment operator

The implicitly-declared or defaulted copy assignment operator for class is defined as deleted in any of the following is true:

  • has a non-static data member that is const
  • has a non-static data member of a reference type.
  • has a non-static data member that cannot be copy-assigned (has deleted, inaccessible, or ambiguous copy assignment operator)
  • has direct or virtual base class that cannot be copy-assigned (has deleted, inaccessible, or ambiguous move assignment operator)
  • has a user-declared move constructor
  • has a user-declared move assignment operator

[edit]Trivial copy assignment operator

The implicitly-declared copy assignment operator for class is trivial if all of the following is true:

  • has no virtual member functions
  • has no virtual base classes
  • The copy assignment operator selected for every direct base of is trivial
  • The copy assignment operator selected for every non-static class type (or array of class type) memeber of is trivial

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

[edit]Implicitly-defined copy assignment operator

If the implicitly-declared copy assignment operator is not deleted or trivial, it is defined (that is, a function body is generated and compiled) by the compiler. For union types, the implicitly-defined copy assignment copies the object representation (as by std::memmove). For non-union class types (class and struct), the operator performs member-wise copy assignment of the object's bases and non-static members, in their initialization order, using, using built-in assignment for the scalars and copy assignment operator for class types.

The generation of the implicitly-defined copy assignment operator is deprecated(since C++11) if has a user-declared destructor or user-declared copy constructor.

[edit]Notes

If both copy and move assignment operators are provided, overload resolution selects the move assignment if the argument is an rvalue (either prvalue such as a nameless temporary or xvalue such as the result of std::move), and selects the copy assignment if the argument is lvalue (named object or a function/operator returning lvalue reference). If only the copy assignment is provided, all argument categories select it (as long as it takes its argument by value or as reference to const, since rvalues can bind to const references), which makes copy assignment the fallback for move assignment, when move is unavailable.

[edit]Copy and swap

Copy assignment operator can be expressed in terms of copy constructor, destructor, and the swap() member function, if one is provided:

T& T::operator=(T arg){// copy/move constructor is called to construct arg
    swap(arg);// resources exchanged between *this and arg
return*this;
}// destructor is called to release the resources formerly held by *this

For non-throwing swap(), this form provides strong exception guarantee. For rvalue arguments, this form automatically invokes the move constructor, and is sometimes referred to as "unifying assignment operator" (as in, both copy and move).

[edit]Example

run this code

Output:

#include <iostream>#include <memory>struct A {int n;std::string s1;// user-defined copy assignment, copy-and-swap form A& operator=(A other){std::cout<<"copy assignment of A\n";std::swap(n, other.n);std::swap(s1, other.s1);return*this;}};struct B : A {std::string s2;// implicitly-defined copy assignment};struct C {std::unique_ptr<int[]> data;std::size_t size;// non-copy-and-swap assignment C& operator=(const C& other){// check for self-assignmentif(&other == this)return*this;// reuse storage when possibleif(size != other.size) data.reset(new int[other.size]);std::copy(&other.data[0], &other.data[0]+std::min(size, other.size), &data[0]);return*this;}// note: copy-and-swap would always cause a reallocation};int main(){ A a1, a2;std::cout<<"a1 = a2 calls "; a1 = a2;// user-defined copy assignment   B b1, b2; b2.s1="foo"; b2.s2="bar";std::cout<<"b1 = b2 calls "; b1 = b2;// implicitly-defined copy assignmentstd::cout<<"b1.s1 = "<< b1.s1<<" b1.s2 = "<< b1.s2<<'\n';}
a1 = a2 calls copy assignment of A b1 = b2 calls copy assignment of A b1.s1 = foo b1.s2 = bar

0 Replies to “Call Assignment Operator Of Base Class Library”

Lascia un Commento

L'indirizzo email non verrà pubblicato. I campi obbligatori sono contrassegnati *