Přiřazení a inicializace související se členy
Metody výchozího přiřazení a inicializace jsou „přiřazení podle členů“ a „inicializace podle členů“.Přiřazení podle členů se skládá z kopírování jednoho objektu do druhého po jednom členu, jako by každý člen byl přiřazen samostatně.Inicializace podle členů se skládá z kopírování jednoho objektu do druhého po jednom členu, jako by každý člen byl inicializován samostatně.Hlavní rozdíl mezi těmito dvěma je, že přiřazení podle členů vyvolá operátor přiřazení jednotlivých členů (operator=), kdežto inicializace podle členů vyvolá kopírovací konstruktor každého členu.
Přiřazení podle členů je provedeno pouze operátorem přiřazení, který je deklarován ve tvaru:
type**&** type :: operator=( [const | volatile] type**&** )
Výchozí operátory přiřazení pro přiřazení podle členů nelze vygenerovat, pokud existuje některá z následujících podmínek:
Členská třída má členy const.
Členská třída má odkazové členy.
Členská třída nebo její základní třída má soukromý operátor přiřazení (operator=).
Základní třída nebo členská třída nemá žádný operátor přiřazení (operator=).
Výchozí kopírovací konstruktory pro inicializaci podle členů nelze vygenerovat, pokud má tato třída nebo některá z jejích základních tříd soukromý kopírovací konstruktor nebo pokud existuje některá z následujících podmínek:
Členská třída má členy const.
Členská třída má odkazové členy.
Členská třída nebo její základní třída má soukromý kopírovací konstruktor.
Základní třída nebo členská třída nemá žádný kopírovací konstruktor.
Výchozí operátory přiřazení a kopírovací konstruktory jsou pro danou třídu vždy deklarovány, ale nejsou definovány, pokud jsou splněny obě následující podmínky:
Třída neposkytuje uživatelem definovanou funkci pro tuto kopii.
Program vyžaduje, aby funkce byla přítomna.Tento požadavek existuje, pokud je očekáváno přiřazení nebo inicializace vyžadující kopírování podle členů nebo pokud je přijata adresa funkce operator= třídy.
Nejsou-li obě tyto podmínky splněny, kompilátor není povinen vygenerovat kód pro výchozí operátor přiřazení a funkce kopírovacího konstruktoru (eliminace takového kódu je optimalizace, kterou provádí kompilátor jazyka C++ společnosti Microsoft).Konkrétně, pokud třída deklaruje uživatelem definovanou funkci operator=, která přijímá argument typu „odkaz na název třídy“, není vygenerován žádný výchozí operátor přiřazení.Pokud třída deklaruje kopírovací konstruktor, není vygenerován žádný výchozí kopírovací konstruktor.
Proto jsou pro danou třídu A vždy k dispozici následující deklarace:
// Implicit declarations of copy constructor
// and assignment operator.
A::A( const A& );
A& A::operator=( const A& );
Definice jsou zadány pouze v případě, že jsou vyžadovány (podle předchozího kritéria).Funkce kopírovacího konstruktoru znázorněné v předchozím příkladu jsou považovány za veřejné členské funkce třídy.
Výchozí operátory přiřazení umožňují objekty dané třídy přiřadit objektům veřejného typu základní třídy.Uvažujme následující kód:
Příklad
// 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());
}
Komentář
V předchozím příkladu je vybrán operátor přiřazení Account::operator=.Protože výchozí funkce operator= přijímá argument typu Account& (odkaz na typ Account), podřízený objekt Account v proměnné checking je zkopírován do proměnné account. Proměnná fOverdraftProtect není zkopírována.