Partilhar via


Inicialização e atribuição com reconhecimento de membro

Os métodos para a atribuição padrão e a inicialização são “atribuição a todos os membros” e “inicialização a todos os membros”, respectivamente. A atribuição a todos os membros consiste em copiar um objeto para outro, um membro de cada vez, como se atribuísse cada membro individualmente. A inicialização a todos os membros consiste em copiar um objeto para outro, um membro de cada vez, como se inicializasse cada membro individualmente. A principal diferença entre os dois é que a atribuição a todos os membros invoca o operador de atribuição de cada membro (operator=), enquanto que a inicialização a todos os membros invoca o construtor de cópia de cada membro.

A atribuição a todos os membros é executada somente pelo operador de atribuição declarado no formato:

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

Os operadores de atribuição padrão para a atribuição a todos os membros não podem ser gerados se qualquer uma das seguintes condições:

  • Uma classe de membro tem membros const.

  • Uma classe de membro tem membros de referência.

  • Uma classe de membro ou sua classe base tem um operador de atribuição particular (operator=).

  • Uma classe base ou classe de membro não tem um operador de atribuição (operator=).

Os construtores padrão de cópia para a inicialização a todos os membros não podem ser gerados se a classe ou uma de suas classes base tiver um construtor particular de cópia ou se alguma das seguintes condições:

  • Uma classe de membro tem membros const.

  • Uma classe de membro tem membros de referência.

  • Uma classe de membro ou sua classe base tem um construtor de cópia particular.

  • Uma classe base ou classe de membro não tem construtor de cópia.

Os operadores de atribuição e os construtores padrão de cópia de uma determinada classe são declarados sempre, mas não são definidos, a menos que ambas as condições seguintes sejam cumpridas:

  • A classe não fornece uma função definida pelo usuário para essa cópia.

  • O programa requer que a função esteja presente. Esse requisito existe se uma atribuição ou uma inicialização for encontrada que requer a cópia de todos os membros ou se o endereço da função operator= de classe for usado.

Se essas duas condições não forem atendidas, o compilador não será obrigado a gerar código para as funções de construtor padrão do operador de atribuição e de impressão (a eliminação desse código é uma otimização executada pelo compilador do Microsoft C++). Especificamente, se a classe declarar uma operator= definida pelo usuário que usa um argumento do tipo "referência a class-name", nenhum operador de atribuição padrão será gerado especificamente. Se a classe declarar um construtor de cópia, nenhum construtor padrão de cópia será gerado.

Portanto, para uma determinada classe A, as seguintes declarações estarão sempre presentes:

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

As definições são fornecidas somente quando necessário (de acordo com os critérios acima). As funções do construtor de cópia mostradas no exemplo acima são consideradas funções de membro públicas da classe.

Os operadores de atribuição padrão permitem que os objetos de uma classe específica sejam atribuídos a objetos de um tipo público de classe base. Considere o código a seguir:

Exemplo

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

Comment

No exemplo anterior, o operador de atribuição é escolhido Account::operator=. Como a função operator= padrão usa um argumento do tipo Account& (referência a Account), o subobjeto Account de checking é copiado para account; fOverdraftProtect não é copiado.

Consulte também

Referência

Copiando objetos de classe