Partager via


Assignation et initialisation de membre à membre

Les méthodes pour l'assignation et l'initialisation par défaut sont « l'assignation de membre » et « l'initialisation de membre, » respectivement. L'assignation de membre consiste à copier un objet dans un autre, un membre à la fois, comme s'il s'agissait d'assigner chaque membre individuellement. L'initialisation de membre consiste à copier un objet dans un autre, un membre à la fois, comme s'il s'agissait d'initialiser chaque membre individuellement. La principale différence entre les deux est que l'assignation de membre appelle l'opérateur d'assignation de chaque membre (operator=), alors que l'initialisation de membre appelle le constructeur de copie de chaque membre.

L'assignation de membre est exécutée uniquement par l'opérateur d'assignation déclaré comme suit :

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

Les opérateurs d'assignation par défaut pour l'assignation de membre ne peuvent être générés si l'une des conditions suivantes existe :

  • Une classe membre a des membres const.

  • Une classe membre a des membres de référence.

  • Une classe membre ou sa classe de base a un opérateur d'assignation privé (operator=).

  • Une classe de base ou une classe membre n'a aucun opérateur d'assignation (operator=).

Les constructeurs de copie par défaut pour l'initialisation de membre ne peuvent être générés si la classe ou une de ses classes de base a un constructeur de copie privé ou si l'une des conditions suivantes existent :

  • Une classe membre a des membres const.

  • Une classe membre a des membres de référence.

  • Une classe membre ou sa classe de base a un constructeur de copie privé.

  • Une classe de base ou une classe membre n'a aucun constructeur de copie.

Les opérateurs d'assignation par défaut et les constructeurs de copie pour une classe donnée sont toujours déclarés, mais ils ne sont pas définis à moins que les deux conditions suivantes soient remplies :

  • La classe ne fournit pas de fonction définie par l'utilisateur pour cette copie.

  • Le programme requiert que la fonction soit présente. Cette spécification existe si une assignation ou une initialisation est produite qui nécessite une copie de membre ou si l'adresse de la fonction operator= de la classe est effectuée.

Si les deux conditions ne sont pas respectées, le compilateur n'est pas nécessaire pour générer le code pour l'opérateur d'assignation par défaut et un constructeur de copie s'exécute (l'élimination du code correspondant est une optimisation exécutée par le compilateur Microsoft C++). Plus particulièrement, si la classe déclare operator= défini par l'utilisateur qui prend un argument de type « référence au class-name », aucun opérateur d'assignation par défaut n'est généré. Si la classe déclare un constructeur de copie, aucun constructeur de copie par défaut n'est généré.

Par conséquent, pour une classe donnée A, les déclarations suivantes sont toujours présentes :

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

Les définitions sont fournies uniquement si nécessaire (selon les critères précédents). Les fonctions de constructeur de copie indiquées dans l'exemple précédent sont considérées comme des fonctions membres publiques de la classe.

Les opérateurs d'assignation par défaut permettent aux objets d'une classe donnée d'être assignés aux objets d'un type public de classe de base. Examinons le code ci-dessous.

Exemple

// 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());
}
  

Commentaire

Dans l'exemple précédent, l'opérateur d'assignation choisi est Account::operator=. La fonction operator= par défaut prend un argument de type Account& (référence à Account), le sous-objet Account de checking est copié dans account ; fOverdraftProtect n'est pas copié.

Voir aussi

Référence

Copie des objets de classe