Поделиться через


Memberwise Assignment and Initialization

The methods for default assignment and initialization are "memberwise assignment" and "memberwise initialization," respectively. Memberwise assignment consists of copying one object to the other, a member at a time, as if assigning each member individually. Memberwise initialization consists of copying one object to the other, a member at a time, as if initializing each member individually. The primary difference between the two is that memberwise assignment invokes each member's assignment operator (operator=), whereas memberwise initialization invokes each member's copy constructor.

Memberwise assignment is performed only by the assignment operator declared in the form:

type**&** type :: operator=( [const | volatile] type**&** )

Default assignment operators for memberwise assignment cannot be generated if any of the following conditions exist:

  • A member class has const members.

  • A member class has reference members.

  • A member class or its base class has a private assignment operator (operator=).

  • A base class or member class has no assignment operator (operator=).

Default copy constructors for memberwise initialization cannot be generated if the class or one of its base classes has a private copy constructor or if any of the following conditions exist:

  • A member class has const members.

  • A member class has reference members.

  • A member class or its base class has a private copy constructor.

  • A base class or member class has no copy constructor.

The default assignment operators and copy constructors for a given class are always declared, but they are not defined unless both of the following conditions are met:

  • The class does not provide a user-defined function for this copy.

  • The program requires that the function be present. This requirement exists if an assignment or initialization is encountered that requires memberwise copying or if the address of the class's operator= function is taken.

If both of these conditions are not met, the compiler is not required to generate code for the default assignment operator and copy constructor functions (elimination of such code is an optimization performed by the Microsoft C++ compiler). Specifically, if the class declares a user-defined operator= that takes an argument of type "reference to class-name," no default assignment operator is generated. If the class declares a copy constructor, no default copy constructor is generated.

Therefore, for a given class A, the following declarations are always present:

//  Implicit declarations of copy constructor
//   and assignment operator.
A::A( const A& );
A& A::operator=( const A& );

The definitions are supplied only if required (according to the preceding criteria). The copy constructor functions shown in the preceding example are considered public member functions of the class.

Default assignment operators allow objects of a given class to be assigned to objects of a public base-class type. Consider the following code:

Example

// spec1_memberwise_assignment_and_initialization.cpp

#include<stdio.h>

class Account
{
protected:
    int _balance;
public:
   int getBalance() 
   {
      return _balance;
   }
};

class Checking : public Account
{
private:
    int _fOverdraftProtect;
public:
    Checking(int balance, int fOverdraftProtect)
    {
        _balance = balance;
        _fOverdraftProtect = fOverdraftProtect;
    }
};

int main()
{
    Account account;
    Checking checking(1000, 1);
    account = checking;
    printf_s("Account balance = %d\n", account.getBalance());
}
Account balance = 1000

Comment

In the preceding example, the assignment operator chosen is Account::operator=. Because the default operator= function takes an argument of type Account& (reference to Account), the Account subobject of checking is copied to account; fOverdraftProtect is not copied.

See Also

Reference

Copying Class Objects