Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π­Ρ„Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΎΠ΅ использованиС C++. 55 Π²Π΅Ρ€Π½Ρ‹Ρ… способов ΡƒΠ»ΡƒΡ‡ΡˆΠΈΡ‚ΡŒ структуру ΠΈ ΠΊΠΎΠ΄ Π²Π°ΡˆΠΈΡ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 17

Автор Π‘ΠΊΠΎΡ‚Ρ‚ ΠœΠ°ΠΉΠ΅Ρ€Ρ

Widget& Widget::operator=(const Widget& rhs)

{

Bitmap *pOrig = pb; // Π·Π°ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ исходный pb

pb = new Bitmap(*rhs.pb); // ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ pb Π½Π° копию *pb

delete pOrig; // ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ исходный pb

return *this;

}


Π’Π΅ΠΏΠ΅Ρ€ΡŒ, Ссли Β«new BitmapΒ» Π²ΠΎΠ·Π±ΡƒΠ΄ΠΈΡ‚ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅, Ρ‚ΠΎ pb (ΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Widget, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ ΠΎΠ½ ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠΈΡ‚) останСтся Π½Π΅ΠΈΠ·ΠΌΠ΅Π½Π½Ρ‹ΠΌ. Π”Π°ΠΆΠ΅ Π±Π΅Π· ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π½Π° совпадСниС здСсь обрабатываСтся присваиваниС самому сСбС, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΌΡ‹ сдСлали копию исходного ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Bitmap, ΡƒΠ΄Π°Π»ΠΈΠ»ΠΈ Π΅Π³ΠΎ, Π° Π·Π°Ρ‚Π΅ΠΌ Π½Π°ΠΏΡ€Π°Π²ΠΈΠ»ΠΈ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΡΠ΄Π΅Π»Π°Π½Π½ΡƒΡŽ копию. Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, это Π½Π΅ самый эффСктивный способ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ присваиваниС самому сСбС, Π½ΠΎ ΠΎΠ½ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚.

Если Π²Ρ‹ ΠΏΠ΅Ρ‡Π΅Ρ‚Π΅ΡΡŒ ΠΎΠ± эффСктивности, Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ Π½Π° совпадСниС Π² Π½Π°Ρ‡Π°Π»Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. Но ΠΏΡ€Π΅ΠΆΠ΄Π΅ спроситС сСбя, ΠΊΠ°ΠΊ часто ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΎΠΈΡΡ…ΠΎΠ΄ΠΈΡ‚ΡŒ присваиваниС самому сСбС, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Ρ‚ΠΎΠΆΠ΅ Π½Π΅ обходится Π΄Π°Ρ€ΠΎΠΌ. Π­Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ ΠΊΠΎΠ΄ (исходный ΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π½Ρ‹ΠΉ) Ρ‡ΡƒΡ‚ΡŒ большС, Π° Π²Π΅Ρ‚Π²Π»Π΅Π½ΠΈΠ΅ нСсколько сниТаСт ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ исполнСния. Π­Ρ„Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΎΡΡ‚ΡŒ ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ Π²Ρ‹Π±ΠΎΡ€ΠΊΠΈ ΠΊΠΎΠΌΠ°Π½Π΄, ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ ΠΈ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ΠΈΠ·Π°Ρ†ΠΈΠΈ Ρ‚ΠΎΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΡΡ‚Ρ€Π°Π΄Π°Ρ‚ΡŒ.

ΠΠ»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²ΠΎΠΉ Ρ€ΡƒΡ‡Π½ΠΎΠΌΡƒ ΡƒΠΏΠΎΡ€ΡΠ΄ΠΎΡ‡ΠΈΠ²Π°Π½ΠΈΡŽ ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π² operator= ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ обСспСчСниС ΠΈ бСзопасности Π² смыслС ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ, ΠΈ бСзопасности присваивания самому сСбС Π·Π° счСт примСнСния Ρ‚Π΅Ρ…Π½ΠΈΠΊΠΈ «копирования с ΠΎΠ±ΠΌΠ΅Π½ΠΎΠΌΒ» (Β«copy and swapΒ»). Она тСсно связана с Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒΡŽ Π² смыслС ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ, поэтому рассматриваСтся Π² ΠΏΡ€Π°Π²ΠΈΠ»Π΅ 29. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅ это достаточно распространСнный способ написания operator=, ΠΈ Π½Π° Π½Π΅Π³ΠΎ стоит Π²Π·Π³Π»ΡΠ½ΡƒΡ‚ΡŒ:


class Widget {

...

void swap(Widget& rhs); // ΠΎΠ±ΠΌΠ΅Π½ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ *this ΠΈ rhs

... // см. подробности Π² ΠΏΡ€Π°Π²ΠΈΠ»Π΅ 29

};

Widget& Widget:: operator=(const Widget& rhs)

{

Widget temp(rhs); // ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ копию Π΄Π°Π½Π½Ρ‹Ρ… rhs

swap(tmp); // ΠΎΠ±ΠΌΠ΅Π½ΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ *this с ΠΊΠΎΠΏΠΈΠ΅ΠΉ

return *this;

}


Π—Π΄Π΅ΡΡŒ ΠΌΡ‹ ΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡΡ Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ: (1) ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ присваивания ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±ΡŠΡΠ²ΠΈΡ‚ΡŒ ΠΊΠ°ΠΊ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰ΠΈΠΌ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ ΠΏΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ ΠΈ (2) ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΏΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ созданиС ΠΊΠΎΠΏΠΈΠΈ этого ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° (см. ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ 20):


Widget& Widget::operator=(Widget rhs) // rhs – копия ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°

{ // ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Ρƒ ΠΏΠΎ

// Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ

swap(rhs); // ΠΎΠ±ΠΌΠ΅Π½ΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ *this с ΠΊΠΎΠΏΠΈΠ΅ΠΉ

return *this;

}


Π›ΠΈΡ‡Π½ΠΎ мСня бСспокоит, Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ приносит ΡΡΠ½ΠΎΡΡ‚ΡŒ Π² ΠΆΠ΅Ρ€Ρ‚Π²Ρƒ изощрСнности, Π½ΠΎ, пСрСмСщая ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ копирования ΠΈΠ· Ρ‚Π΅Π»Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π² конструированиС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°, компилятор ΠΈΠ½ΠΎΠ³Π΄Π° ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠ³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ эффСктивный ΠΊΠΎΠ΄.

Π§Ρ‚ΠΎ слСдуСт ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ

β€’ Π£Π±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ operator= ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ Π²Π΅Π΄Π΅Ρ‚ сСбя, ΠΊΠΎΠ³Π΄Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ присваиваСтся самому сСбС. Для этого ΠΌΠΎΠΆΠ½ΠΎ ΡΡ€Π°Π²Π½ΠΈΡ‚ΡŒ адрСса исходного ΠΈ Ρ†Π΅Π»Π΅Π²ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², Π°ΠΊΠΊΡƒΡ€Π°Ρ‚Π½ΠΎ ΡƒΠΏΠΎΡ€ΡΠ΄ΠΎΡ‡ΠΈΡ‚ΡŒ прСдлоТСния ΠΈΠ»ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΈΠ΄ΠΈΠΎΠΌΡƒ копирования ΠΎΠ±ΠΌΠ΅Π½ΠΎΠΌ.

β€’ Π£Π±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ всС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΎΠΏΠ΅Ρ€ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠ΅ Π±ΠΎΠ»Π΅Π΅ Ρ‡Π΅ΠΌ ΠΎΠ΄Π½ΠΈΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ, Π²Π΅Π΄ΡƒΡ‚ сСбя ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ ΠΏΡ€ΠΈ совпадСнии Π΄Π²ΡƒΡ… ΠΈΠ»ΠΈ Π±ΠΎΠ»Π΅Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ².

ΠŸΡ€Π°Π²ΠΈΠ»ΠΎ 12: ΠšΠΎΠΏΠΈΡ€ΡƒΠΉΡ‚Π΅ всС части ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°

Π’ Ρ…ΠΎΡ€ΠΎΡˆΠΎ спроСктированных ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π½ΠΎ-ΠΎΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… систСмах, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΠ½ΠΊΠ°ΠΏΡΡƒΠ»ΠΈΡ€ΡƒΡŽΡ‚ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅Π΅ устройство ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ Π·Π°Π½ΠΈΠΌΠ°ΡŽΡ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π΄Π²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ: конструктор копирования ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ присваивания. НазовСм ΠΈΡ… функциями копирования. Π’ ΠΏΡ€Π°Π²ΠΈΠ»Π΅ 5 я Π³ΠΎΠ²ΠΎΡ€ΠΈΠ», Ρ‡Ρ‚ΠΎ компилятор Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΡ€ΠΈ нСобходимости, ΠΈ объяснял, Ρ‡Ρ‚ΠΎ сгСнСрированныС компилятором вСрсии Π΄Π΅Π»Π°ΡŽΡ‚ Ρ‚ΠΎΡ‡Π½ΠΎ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π²Ρ‹ ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚Π΅: копию всСх Π΄Π°Π½Π½Ρ‹Ρ… исходного ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.

Объявляя собствСнныС ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π²Ρ‹ сообщаСтС компилятору, Ρ‡Ρ‚ΠΎ рСализация ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π²Π°ΠΌ Ρ‡Π΅ΠΌ-Ρ‚ΠΎ Π½Π΅ нравится. ΠšΠΎΠΌΠΏΠΈΠ»ΡΡ‚ΠΎΡ€ «обиТаСтся» ΠΈ мстит ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½Ρ‹ΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ: ΠΎΠ½ Π½Π΅ сообщаСт, Ссли Π² вашСй Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ.

Рассмотрим класс, ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‰ΠΈΠΉ Π·Π°ΠΊΠ°Π·Ρ‡ΠΈΠΊΠΎΠ², Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ написаны Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΈΡ… Π²Ρ‹Π·ΠΎΠ²Ρ‹ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»ΠΈΡ€ΡƒΡŽΡ‚ΡΡ:


void logCall(const std::string& funcName); // Π΄Π΅Π»Π°Π΅Ρ‚ запись Π² ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»

class Customer {

public:

...

Customer(const Customer& rhs);

Customer& operator=(const Customer& rhs);

...

private:

std::string name;

};

Customer::Customer(const Customer& rhs)

: name(rhs.name) // ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ rhs

{

logCall(β€œΠšΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ‚ΠΎΡ€ копирования Customer”);

}

Customer& Customer::operator=(const Customer& rhs)

{

logCall(β€œΠšΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ присвоСния Customer”);

name = rhs.name; // ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ rhs

return *this; // см. ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ 10

}


ВсС здСсь выглядит ΠΎΡ‚Π»ΠΈΡ‡Π½ΠΎ, ΠΈ Π½Π° самом Π΄Π΅Π»Π΅ Ρ‚Π°ΠΊ ΠΎΠ½ΠΎ ΠΈ Π΅ΡΡ‚ΡŒ – Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° Π² класс Customer Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ Π½ΠΎΠ²Ρ‹ΠΉ Ρ‡Π»Π΅Π½:


class Date {...}; // для Π΄Π°Ρ‚Ρ‹ ΠΈ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ

class Customer {

public:

... // ΠΊΠ°ΠΊ Ρ€Π°Π½ΡŒΡˆΠ΅

private:

std::string name;

Date lastTransaction;

};


Π‘ этого ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ копирования ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Π°ΡΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, ΠΈΠΌΠ΅Π½Π½ΠΎ ΠΏΠΎΠ»Π΅ name, Π½ΠΎ Π½Π΅ ΠΏΠΎΠ»Π΅ lastTransaction. Однако Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²ΠΎ компиляторов Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ скаТут ΠΎΠ± этом Π΄Π°ΠΆΠ΅ ΠΏΡ€ΠΈ установкС максимального уровня диагностики (см. Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ 53). Π’ΠΎΡ‚ ΠΊ Ρ‡Π΅ΠΌΡƒ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ написаниС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ копирования. Π’Ρ‹ ΠΎΡ‚Π²Π΅Ρ€Π³Π°Π΅Ρ‚Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ компилятор, поэтому ΠΎΠ½ Π½Π΅ сообщаСт, Ρ‡Ρ‚ΠΎ ваш ΠΊΠΎΠ΄ Π½Π΅ ΠΏΠΎΠ»ΠΎΠ½. РСшСниС ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½ΠΎ: Ссли Π²Ρ‹ добавляСтС Π½ΠΎΠ²Ρ‹ΠΉ Ρ‡Π»Π΅Π½ Π² класс, Ρ‚ΠΎ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΎΠ±Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΈ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ (Π° Ρ‚Π°ΠΊΠΆΠ΅ всС конструкторы [см. ΠΏΡ€Π°Π²ΠΈΠ»Π° 4 ΠΈ 45] ΠΈ всС нСстандартныС Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹ operator= Π² классС [ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π² ΠΏΡ€Π°Π²ΠΈΠ»Π΅ 10]; Ссли Π²Ρ‹ Π·Π°Π±ΡƒΠ΄Π΅Ρ‚Π΅, Ρ‚ΠΎ компилятор вряд Π»ΠΈ Π½Π°ΠΏΠΎΠΌΠ½ΠΈΡ‚).

Одним ΠΈΠ· Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΠΊΠΎΠ²Π°Ρ€Π½Ρ‹Ρ… случаСв проявлСния этой ситуации являСтся наслСдованиС. Рассмотрим ΠΏΡ€ΠΈΠΌΠ΅Ρ€:


class PriorityCustomer: public Customer { // ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½Ρ‹ΠΉ класс

public:

...

PriorityCustomer(const PriorityCustomer& rhs);

PriorityCustomer& operator=(const PriorityCustomer& rhs);

...

private:

int priority;

};

PriorityCustomer::PriorityCustomer(const PriorityCustomer& rhs)

: priority(rhs.priority)

{

logCall(β€œΠšΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ‚ΠΎΡ€ копирования PriorityCustomer”);

}

PriorityCustomer&

PriorityCustomer::operator=(const PriorityCustomer& rhs)

{

logCall(β€œΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ присваивания PriorityCustomer”);

priority = rhs. Priority;

return *this;

}


На ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ взгляд, ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π² классС PriorityCustomer ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‚ всС Π΅Π³ΠΎ Ρ‡Π»Π΅Π½Ρ‹, Π½ΠΎ ΠΏΡ€ΠΈΠ³Π»ΡΠ΄ΠΈΡ‚Π΅ΡΡŒ Π²Π½ΠΈΠΌΠ°Ρ‚Π΅Π»ΡŒΠ½Π΅Π΅. Π”Π°, ΠΎΠ½ΠΈ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‚ Π΄Π°Π½Π½Ρ‹Π΅-Ρ‡Π»Π΅Π½Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½Ρ‹ Π² PriorityCustomer, Π½ΠΎ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ PriorityCustomer Ρ‚Π°ΠΊΠΆΠ΅ содСрТит Ρ‡Π»Π΅Π½Ρ‹, унаслСдованныС ΠΎΡ‚ Customer, Π° ΠΎΠ½ΠΈ-Ρ‚ΠΎ Π½Π΅ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‚ΡΡ вовсС! ΠšΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ‚ΠΎΡ€ копирования PriorityCustomer Π½Π΅ спСцифицируСт Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Ρ‹ конструктору Π΅Π³ΠΎ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ класса (Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ Π½Π΅ ΡƒΠΏΠΎΠΌΠΈΠ½Π°Π΅Ρ‚ Customer Π² своСм спискС ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Ρ‡Π»Π΅Π½ΠΎΠ²), поэтому Ρ‡Π°ΡΡ‚ΡŒ Customer ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° PriorityCustomer Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π° конструктором Customer, Π½Π΅ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰ΠΈΠΌ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ², конструктором ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ (Ссли ΠΎΠ½ отсутствуСт, Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠΉ ΠΊΠΎΠ΄ просто Π½Π΅ скомпилируСтся). Π­Ρ‚ΠΎΡ‚ конструктор выполняСт ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Ρ‡Π»Π΅Π½ΠΎΠ² name ΠΈ lastTransaction.

Для ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° присваивания PriorityCustomer ситуация ΠΌΠ°Π»ΠΎ Ρ‡Π΅ΠΌ отличаСтся. Он Π½Π΅ выполняСт Π½ΠΈΠΊΠ°ΠΊΠΈΡ… ΠΏΠΎΠΏΡ‹Ρ‚ΠΎΠΊ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅-Ρ‡Π»Π΅Π½Ρ‹ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ класса, поэтому ΠΎΠ½ΠΈ ΠΎΡΡ‚Π°ΡŽΡ‚ΡΡ Π½Π΅ΠΈΠ·ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ.

Всякий Ρ€Π°Π·, ΠΊΠΎΠ³Π΄Π° Π²Ρ‹ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΏΠΈΡˆΠ΅Ρ‚Π΅ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ для ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½ΠΎΠ³ΠΎ класса, ΠΏΠΎΠ·Π°Π±ΠΎΡ‚ΡŒΡ‚Π΅ΡΡŒ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ части Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ класса. ΠžΠ±Ρ‹Ρ‡Π½ΠΎ ΠΎΠ½ΠΈ находятся Π² Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΎΠΌ Ρ€Π°Π·Π΄Π΅Π»Π΅ класса (см. ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ 22), поэтому Ρƒ вас Π½Π΅Ρ‚ прямого доступа ΠΊ Π½ΠΈΠΌ. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½ΠΎΠ³ΠΎ класса Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ класса:


PriorityCustomer::PriorityCustomer(const PriorityCustomer& rhs)

: Customer(rhs), // Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ конструктор

// базового класса

priority(rhs.priority)

{

logCall(β€œΠšΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ‚ΠΎΡ€ копирования PriorityCustomer”);

}

PriorityCustomer&

PriorityCustomer::operator=(const PriorityCustomer& rhs)

{

logCall(β€œΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ присваивания PriorityCustomer”);

Customer::operator=(rhs); // ΠΏΡ€ΠΈΡΠ²ΠΎΠΈΡ‚ΡŒ значСния Π΄Π°Π½Π½Ρ‹ΠΌ-Ρ‡Π»Π΅Π½Π°ΠΌ

// базового класса

priority = rhs. Priority;

return *this;

}


Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ„Ρ€Π°Π·Ρ‹ Β«ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ всС части» Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ΅ этого ΠΏΠ°Ρ€Π°Π³Ρ€Π°Ρ„Π° Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ понятно. Когда Π²Ρ‹ ΠΏΠΈΡˆΠ΅Ρ‚Π΅ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΡƒΠ±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ (1) ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‚ΡΡ всС Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅-Ρ‡Π»Π΅Π½Ρ‹ ΠΈ (2) Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ всСх Π±Π°Π·ΠΎΠ²Ρ‹Ρ… классов.

На ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅ эти Π΄Π²Π΅ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ часто ΠΈΠΌΠ΅ΡŽΡ‚ ΠΏΠΎΡ…ΠΎΠΆΠΈΠ΅ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ, ΠΈ Ρƒ вас ΠΌΠΎΠΆΠ΅Ρ‚ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΡƒΡ‚ΡŒ соблазн ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ дублирования ΠΊΠΎΠ΄Π° Π·Π° счСт Π²Ρ‹Π·ΠΎΠ²Π° ΠΎΠ΄Π½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΎΠΉ. Π’Π°ΠΊΠΎΠ΅ стрСмлСниС ΠΏΠΎΡ…Π²Π°Π»ΡŒΠ½ΠΎ, Π½ΠΎ Π²Ρ‹Π·ΠΎΠ² ΠΎΠ΄Π½ΠΎΠΉ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰Π΅ΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΎΠΉ – Π½Π΅Π²Π΅Ρ€Π½Ρ‹ΠΉ ΠΏΡƒΡ‚ΡŒ.

НСт смысла Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ конструктор копирования ΠΈΠ· ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° присваивания, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π²Ρ‹ Ρ‚Π΅ΠΌ самым ΠΏΠΎΠΏΡ‹Ρ‚Π°Π΅Ρ‚Π΅ΡΡŒ ΡΠΊΠΎΠ½ΡΡ‚Ρ€ΡƒΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΡƒΠΆΠ΅ сущСствуСт. Π­Ρ‚ΠΎ Π½Π°ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ бСссмыслСнно, Ρ‡Ρ‚ΠΎ Π΄Π°ΠΆΠ΅ Π½Π΅ сущСствуСт синтаксиса для Ρ‚Π°ΠΊΠΎΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ. Π•ΡΡ‚ΡŒ синтаксис, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ выглядит Ρ‚Π°ΠΊ, Π±ΡƒΠ΄Ρ‚ΠΎ Π²Ρ‹ Π΄Π΅Π»Π°Π΅Ρ‚Π΅ это, хотя Π½Π° самом Π΄Π΅Π»Π΅ ΠΎΠ½ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ совсСм ΠΈΠ½ΠΎΠ΅. Π•ΡΡ‚ΡŒ Ρ‚Π°ΠΊΠΆΠ΅ синтаксис, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ позволяСт это ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ, Π½ΠΎ ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎ Π½Π΅ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½Ρ‹ΠΌ способом, ΠΏΡ€ΠΈΡ‡Π΅ΠΌ ΠΏΡ€ΠΈ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… условиях ваш ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎΠ²Ρ€Π΅ΠΆΠ΄Π΅Π½. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ я Π½Π΅ ΠΏΠΎΠΊΠ°ΠΆΡƒ Π½ΠΈ Ρ‚ΠΎΡ‚, Π½ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠΉ. ΠŸΡ€ΠΎΡΡ‚ΠΎ ΠΏΡ€ΠΈΠΌΠΈΡ‚Π΅ ΠΊΠ°ΠΊ Π΄Π°Π½Π½ΠΎΡΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΈΠ· ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° присваивания конструктор копирования Π½Π΅ слСдуСт.