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

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

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

Для Ρ‡Π΅Π³ΠΎ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹Π΅ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Ρ…ΠΎΡ€ΠΎΡˆΠΈ – Ρ‚Π°ΠΊ это для ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ нСявных ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠΉ Ρ‚ΠΈΠΏΠΎΠ². Π£ΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π½Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½Ρ‹Ρ… классов нСявно ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΡŽΡ‚ΡΡ Π² ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π½Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π±Π°Π·ΠΎΠ²Ρ‹Ρ… классов, ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π½Π° нСконстантныС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ – Π² ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π½Π° константныС ΠΈ Ρ‚. ΠΏ. НапримСр, рассмотрим Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ прСобразования, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΡ€ΠΎΠΈΡΡ…ΠΎΠ΄ΠΈΡ‚ΡŒ Π² Ρ‚Ρ€Π΅Ρ…ΡƒΡ€ΠΎΠ²Π½Π΅Π²ΠΎΠΉ ΠΈΠ΅Ρ€Π°Ρ€Ρ…ΠΈΠΈ:


class Top {...};

class Middle: public Top {...};

class Bottom: public Middle {...};

Top *pt1 = new Middle; // ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ Middle* Π² Top*

Top *pt2 = new Bottom; // ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ Middle* Π² Bottom*

Const Top *pct2 = pt1; // ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ Top* Π² const Top*


Π­ΠΌΡƒΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚Π°ΠΊΠΈΠ΅ прСобразования с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ опрСдСляСмых ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΌ Β«ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Ρ…Β» ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ Π½Π΅ просто. Для этого Π½ΡƒΠΆΠ½ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ компилировался Ρ‚Π°ΠΊΠΎΠΉ ΠΊΠΎΠ΄:


Template<typename T>

class SmartPtr {

public:

explicit SmartPtr(T *realPtr); // ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Π΅ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ

... // ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΡŽΡ‚ΡΡ встроСнными

}; // указатСлями

SmartPtr<Top> pt1 = // ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ SmartPtr<Middle>

SmartPtr<Middle>(new Middle); // Π² SmartPtr<Top>

SmartPtr<Top> pt2 = // ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ SmartPtr<Bottom>

SmartPtr<Bottom>(new Bottom); // SmartPtr<Top>

SmartPtr<const Top> pct2 = pt1;


Π Π°Π·Π½Ρ‹Π΅ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ шаблона Π½Π΅ связаны ΠΊΠ°ΠΊΠΈΠΌ-Π»ΠΈΠ±ΠΎ ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΠ΅ΠΌ, поэтому компилятор считаСт, Ρ‡Ρ‚ΠΎ SmartPtr<Middle> ΠΈ SmartPtr<Top> β€“ ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎ Ρ€Π°Π·Π½Ρ‹Π΅ классы, Π½Π΅ Π±ΠΎΠ»Π΅Π΅ связанныС Π΄Ρ€ΡƒΠ³ с Π΄Ρ€ΡƒΠ³ΠΎΠΌ, Ρ‡Π΅ΠΌ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, vector<float> ΠΈ Widget. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²Π»ΡΡ‚ΡŒ прСобразования ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ классами SmartPtr, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ явно Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄. Π’ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΌ Π²Ρ‹ΡˆΠ΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΈΠ΅ создаСт Π½ΠΎΠ²Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ указатСля, поэтому для Π½Π°Ρ‡Π°Π»Π° сосрСдоточимся Π½Π° написании конструкторов, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±ΡƒΠ΄ΡƒΡ‚ вСсти сСбя Ρ‚Π°ΠΊ, ΠΊΠ°ΠΊ Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ. ΠšΠ»ΡŽΡ‡Π΅Π²ΠΎΠ΅ наблюдСниС состоит Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ сразу всС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ конструкторы. Π’ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΉ ΠΈΠ΅Ρ€Π°Ρ€Ρ…ΠΈΠΈ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΊΠΎΠ½ΡΡ‚Ρ€ΡƒΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ SmartPtr<Top> ΠΈΠ· SmartPtr<Middle> ΠΈΠ»ΠΈ SmartPtr<Bottom>, Π½ΠΎ Ссли Π² Π±ΡƒΠ΄ΡƒΡ‰Π΅ΠΌ иСрархия Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½Π°, Ρ‚ΠΎ придСтся Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ конструирования ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² SmartPtr<Top> ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΈΡ… Ρ‚ΠΈΠΏΠΎΠ² ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Ρ… ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ. НапримСр, Ссли ΠΌΡ‹ ΠΏΠΎΠ·ΠΆΠ΅ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Ρ‚Π°ΠΊΠΎΠΉ класс:


class BelowBottom: public Bottom {...};


Ρ‚ΠΎ Π½ΡƒΠΆΠ½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ созданиС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² SmartPtr<Top> ΠΈΠ· SmartPtr<Below-Bottom>, ΠΈ, ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½ΠΎ, Π½Π΅ Ρ…ΠΎΡ‚Π΅Π»ΠΎΡΡŒ Π±Ρ‹ Ρ€Π°Π΄ΠΈ этого ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ шаблон SmartPtr.

Π’ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ΅, Π½Π°ΠΌ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ½Π°Π΄ΠΎΠ±ΠΈΡ‚ΡŒΡΡ Π½Π΅ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½Π½ΠΎΠ΅ число конструкторов. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ шаблон ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½ для Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ Π½Π΅ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½Π½ΠΎΠ³ΠΎ числа Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, ΠΏΠΎΡ…ΠΎΠΆΠ΅, Ρ‡Ρ‚ΠΎ Π½Π°ΠΌ Π½ΡƒΠΆΠ΅Π½ Π½Π΅ конструктор-функция для SmartPtr, Π° конструктор-шаблон. Π­Ρ‚ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ шаблона Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Π° (часто Π½Π°Π·Ρ‹Π²Π°Π΅ΠΌΠΎΠ³ΠΎ шаблонного Ρ‡Π»Π΅Π½Π°), Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ шаблона, Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΡŽΡ‰Π΅Π³ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Ρ‹ класса:


template<typename T>

class SmartPtr {

public:

template<typename U> // ΡˆΠ°Π±Π»ΠΎΠ½Π½Ρ‹ΠΉ Ρ‡Π»Π΅Π½

SmartPtr(const SmartPtr<U>& other); // для Β«ΠΎΠ±ΠΎΠ±Ρ‰Π΅Π½Π½ΠΎΠ³ΠΎ

... // конструктора копирования»

};


Π—Π΄Π΅ΡΡŒ говорится, Ρ‡Ρ‚ΠΎ для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΏΠ°Ρ€Ρ‹ Ρ‚ΠΈΠΏΠΎΠ² T ΠΈ U класс SmartPtr<T> ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ создан ΠΈΠ· SmartPtr<U>, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ SmartPtr<T> ΠΈΠΌΠ΅Π΅Ρ‚ конструктор, ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰ΠΈΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Ρ‚ΠΈΠΏΠ° SmartPtr<U>. ΠŸΠΎΠ΄ΠΎΠ±Π½Ρ‹Π΅ конструкторы, ΡΠΎΠ·Π΄Π°ΡŽΡ‰ΠΈΠ΅ ΠΎΠ΄ΠΈΠ½ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ, Ρ‚ΠΈΠΏ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ являСтся Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚ΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ Ρ‚ΠΎΠ³ΠΎ ΠΆΠ΅ шаблона (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, SmartPtr<T> ΠΈΠ· SmartPtr<U>), ΠΈΠ½ΠΎΠ³Π΄Π° Π½Π°Π·Ρ‹Π²Π°ΡŽΡ‚ ΠΎΠ±ΠΎΠ±Ρ‰Π΅Π½Π½Ρ‹ΠΌΠΈ конструкторами копирования.

ΠžΠ±ΠΎΠ±Ρ‰Π΅Π½Π½Ρ‹ΠΉ конструктор копирования Π² ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΌ Π²Ρ‹ΡˆΠ΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π½Π΅ объявлСн с ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΠΌ explicit. И это сдСлано Π½Π°ΠΌΠ΅Ρ€Π΅Π½Π½ΠΎ. ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΡ Ρ‚ΠΈΠΏΠΎΠ² ΠΌΠ΅ΠΆΠ΄Ρƒ встроСнными Ρ‚ΠΈΠΏΠ°ΠΌΠΈ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΈΠ· указатСля Π½Π° ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½Ρ‹ΠΉ класс ΠΊ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŽ Π½Π° Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ класс) происходят нСявно ΠΈ Π½Π΅ Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ привСдСния, поэтому Ρ€Π°Π·ΡƒΠΌΠ½ΠΎ ΠΈ для ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Ρ… ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ ΡΠΌΡƒΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚Π°ΠΊΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅. ИмСнно поэтому ΠΈ Π½Π΅ ΡƒΠΊΠ°Π·Π°Π½ΠΎ слово explicit Π² объявлСнии ΠΎΠ±ΠΎΠ±Ρ‰Π΅Π½Π½ΠΎΠ³ΠΎ конструктора шаблона.

Π‘ΡƒΠ΄ΡƒΡ‡ΠΈ объявлСн описанным Π²Ρ‹ΡˆΠ΅ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, ΠΎΠ±ΠΎΠ±Ρ‰Π΅Π½Π½Ρ‹ΠΉ конструктор копирования для SmartPtr прСдоставляСт большС, Ρ‡Π΅ΠΌ Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ. Π”Π°, ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΠΈΠΌΠ΅Ρ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ SmartPtr<Top> ΠΈΠ· SmartPtr<Bottom>, Π½ΠΎ вовсС Π½Π΅ просили ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ SmartPtr<Bottom> ΠΈΠ· SmartPtr<Top>, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ это ΠΏΡ€ΠΎΡ‚ΠΈΠ²ΠΎΡ€Π΅Ρ‡ΠΈΡ‚ смыслу ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ наслСдования (см. ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ 32). ΠœΡ‹ Ρ‚Π°ΠΊΠΆΠ΅ Π½Π΅ Ρ…ΠΎΡ‚ΠΈΠΌ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ SmartPtr<int> ΠΈΠ· SmartPtr<double>, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π½Π΅ сущСствуСт нСявного прСобразования int* Π² double*. Каким-Ρ‚ΠΎ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡΡƒΠ·ΠΈΡ‚ΡŒ ΠΌΠ½ΠΎΠ³ΠΎΠΎΠ±Ρ€Π°Π·ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ-Ρ‡Π»Π΅Π½ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ способСн Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ этот шаблон.

ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Ρ, Ρ‡Ρ‚ΠΎ SmartPtr написан ΠΏΠΎ ΠΎΠ±Ρ€Π°Π·Ρ†Ρƒ auto_ptr ΠΈ tr1::shared_ptr, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ прСдоставляСт Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ-Ρ‡Π»Π΅Π½ get, которая Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ копию встроСнного указатСля, хранящСгося Π² ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π΅ Β«ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎΒ» указатСля (см. ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ 15), ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ шаблонного конструктора, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΡ‚ΡŒ Π½Π°Π±ΠΎΡ€ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠΉ:


template<typename T>

class SmartPtr {

public:

template<typename U>

SmartPtr(const SmartPtr<U>& other) // ΠΈΠ½ΠΈΡ†ΠΈΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ этот Ρ…Ρ€Π°Π½ΠΈΠΌΡ‹ΠΉ

:heldPtr(other.get()) {...} // ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΌ, хранящимся

// Π² Π΄Ρ€ΡƒΠ³ΠΎΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π΅

T *get() const { return heldPtr;}

...

private: // встроСнный ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ,

T *heldPtr; // хранящийся Π² Β«ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠΌΒ»

};


ΠœΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ список ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Ρ‡Π»Π΅Π½ΠΎΠ², Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ‡Π»Π΅Π½ Π΄Π°Π½Π½Ρ‹Ρ… SmartPtr<T> Ρ‚ΠΈΠΏΠ° T* ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΌ Ρ‚ΠΈΠΏΠ° U*, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ хранится Π² Smart-Ptr<U>. Π­Ρ‚ΠΎΡ‚ ΠΊΠΎΠ΄ откомпилируСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚ΠΎΠ³Π΄Π°, ΠΊΠΎΠ³Π΄Π° сущСствуСт нСявноС ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ указатСля U* Π² T*, Π° это ΠΊΠ°ΠΊ Ρ€Π°Π· Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ. Π˜Ρ‚Π°ΠΊ, SmartPtr<T> Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΠΈΠΌΠ΅Π΅Ρ‚ ΠΎΠ±ΠΎΠ±Ρ‰Π΅Π½Π½Ρ‹ΠΉ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ конструктор, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ компилируСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚ΠΎΠ³Π΄Π°, ΠΊΠΎΠ³Π΄Π° Π΅ΠΌΡƒ пСрСдаСтся ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ совмСстимого Ρ‚ΠΈΠΏΠ°.

ИспользованиС ΡˆΠ°Π±Π»ΠΎΠ½Π½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ-Ρ‡Π»Π΅Π½ΠΎΠ² Π½Π΅ ограничиваСтся конструкторами. Π•Ρ‰Π΅ ΠΎΠ΄Π½ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠ΅ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Ρ‚Π°ΠΊΠΈΡ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ – ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° присваивания. НапримСр, класс shared_ptr ΠΈΠ· TR1 (см. ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ 13) ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ конструированиС ΠΈΠ· всСх совмСстимых встроСнных ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ, tr1::shared_ptr, auto_ptr ΠΈ tr1::weak_ptr (см. ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ 54), Π° Ρ‚Π°ΠΊΠΆΠ΅ Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ Π² ΠΏΡ€Π°Π²ΠΎΠΉ части ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° присваивания ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° любого ΠΈΠ· этих Ρ‚ΠΈΠΏΠΎΠ², ΠΊΡ€ΠΎΠΌΠ΅ tr1::weak_ptr. НиТС ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ спСцификации TR1 для tr1::shared_ptr; ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈ объявлСнии ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² шаблона ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ΅ слов class, Π° Π½Π΅ typename. Как ΠΎΠ±ΡŠΡΡΠ½ΡΠ΅Ρ‚ΡΡ Π² ΠΏΡ€Π°Π²ΠΈΠ»Π΅ 42, Π² Π΄Π°Π½Π½ΠΎΠΌ контСкстС ΠΎΠ½ΠΈ ΠΎΠ·Π½Π°Ρ‡Π°ΡŽΡ‚ ΠΎΠ΄Π½ΠΎ ΠΈ Ρ‚ΠΎ ΠΆΠ΅.


template<class T> class shared_ptr {

public:

template<class Y> // конструируСт ΠΈΠ·

explicit shared_ptr(Y *p); // любого совмСстимого

template<class Y> // встроСнного указатСля,

shared_ptr(shared_ptr<Y> const& r); // shared_ptr,

template<class Y> // weak_ptr ΠΈΠ»ΠΈ

explicit shared_ptr(weak_ptr<Y> const& r); // auto_ptr

template<class Y>

explicit shared_ptr(auto_ptr<Y>& r);

template<class Y> // присваиваСт

explicit shared_ptr& operator=(shared_ptr<Y> const& r); // любой

template<class Y> // совмСстимый

explicit shared_ptr& operator=(auto_ptr<Y> const& r); // shared_ptr ΠΈΠ»ΠΈ

... // auto_ptr

};


ВсС эти конструкторы ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½Ρ‹ ΠΊΠ°ΠΊ explicit, Π·Π° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ ΠΎΠ±ΠΎΠ±Ρ‰Π΅Π½Π½ΠΎΠ³ΠΎ конструктора копирования. Π­Ρ‚ΠΎ Π·Π½Π°Ρ‡ΠΈΡ‚, Ρ‡Ρ‚ΠΎ нСявныС прСобразования ΠΎΡ‚ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° shared_ptr ΠΊ Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ Π΄ΠΎΠΏΡƒΡΠΊΠ°ΡŽΡ‚ΡΡ, Π½ΠΎ нСявныС прСобразования ΠΎΡ‚ встроСнного указатСля ΠΈΠ»ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ Β«ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎΒ» указатСля Π½Π΅ Π΄ΠΎΠΏΡƒΡΠΊΠ°ΡŽΡ‚ΡΡ. (Π―Π²Π½Ρ‹Π΅ прСобразования – Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ привСдСния Ρ‚ΠΈΠΏΠΎΠ² – Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½Ρ‹). Π’Π°ΠΊΠΆΠ΅ интСрСсно ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° auto_ptr конструктору tr1::shared_ptr ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρƒ присваивания ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ указываСтся Π±Π΅Π· ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π° const, Ρ‚ΠΎΠ³Π΄Π° ΠΊΠ°ΠΊ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Ρ‚ΠΈΠΏΠ° tr1::shared_ptr ΠΈ tr1::weak_ptr константны. Π­Ρ‚ΠΎ слСдствиС Ρ‚ΠΎΠ³ΠΎ Ρ„Π°ΠΊΡ‚Π°, Ρ‡Ρ‚ΠΎ Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ Π΄Ρ€ΡƒΠ³ΠΈΡ… классов ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ auto_ptr ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΡƒΡŽΡ‚ΡΡ ΠΏΡ€ΠΈ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ (см. ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ 13).

Π¨Π°Π±Π»ΠΎΠ½Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Ρ‹ – чудСсная Π²Π΅Ρ‰ΡŒ, Π½ΠΎ ΠΎΠ½ΠΈ Π½Π΅ ΠΎΡ‚ΠΌΠ΅Π½ΡΡŽΡ‚ основных ΠΏΡ€Π°Π²ΠΈΠ» языка. Π’ ΠΏΡ€Π°Π²ΠΈΠ»Π΅ 5 ΠΎΠ±ΡŠΡΡΠ½ΡΠ΅Ρ‚ΡΡ, Ρ‡Ρ‚ΠΎ Π΄Π²Π΅ ΠΈΠ· Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ-Ρ‡Π»Π΅Π½ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ компиляторы ΠΌΠΎΠ³ΡƒΡ‚ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ автоматичСски, β€“ это конструктор копирования ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ присваивания. Π’ классС tr1::shared_ptr объявлСн ΠΎΠ±ΠΎΠ±Ρ‰Π΅Π½Π½Ρ‹ΠΉ конструктор копирования, ΠΈ ясно, Ρ‡Ρ‚ΠΎ Π² случаС совпадСния Ρ‚ΠΈΠΏΠΎΠ² T ΠΈ Y конкрСтизация ΠΎΠ±ΠΎΠ±Ρ‰Π΅Π½Π½ΠΎΠ³ΠΎ конструктора копирования ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ свСдСна ΠΊ созданию Β«ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠ³ΠΎΒ» конструктора копирования. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ вопрос, Ρ‡Ρ‚ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ Π΄Π΅Π»Π°Ρ‚ΡŒ компилятор Π² случаС, ΠΊΠΎΠ³Π΄Π° ΠΎΠ΄ΠΈΠ½ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ tr1::shared_ptr конструируСтся ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Ρ‚ΠΎΠ³ΠΎ ΠΆΠ΅ Ρ‚ΠΈΠΏΠ°: Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ конструктор копирования для tr1::shared_ptr ΠΈΠ»ΠΈ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ±ΠΎΠ±Ρ‰Π΅Π½Π½Ρ‹ΠΉ конструктор копирования ΠΈΠ· шаблона?

Как я сказал, ΡˆΠ°Π±Π»ΠΎΠ½Π½Ρ‹Π΅ Ρ‡Π»Π΅Π½Ρ‹ Π½Π΅ ΠΎΡ‚ΠΌΠ΅Π½ΡΡŽΡ‚ основных ΠΏΡ€Π°Π²ΠΈΠ» языка, Π° ΠΈΠ· этих ΠΏΡ€Π°Π²ΠΈΠ» слСдуСт, Ρ‡Ρ‚ΠΎ Ссли конструктор копирования Π½ΡƒΠΆΠ΅Π½, Π° Π²Ρ‹ Π½Π΅ ΠΎΠ±ΡŠΡΠ²Π»ΡΠ΅Ρ‚Π΅ Π΅Π³ΠΎ, Ρ‚ΠΎ ΠΎΠ½ Π±ΡƒΠ΄Π΅Ρ‚ сгСнСрирован автоматичСски. ОбъявлСниС Π² классС ΠΎΠ±ΠΎΠ±Ρ‰Π΅Π½Π½ΠΎΠ³ΠΎ конструктора копирования (шаблонного Ρ‡Π»Π΅Π½Π°) Π½Π΅ ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ компилятором ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠ³ΠΎ конструктора копирования. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Ссли Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ всС аспСкты конструирования ΠΏΡƒΡ‚Π΅ΠΌ копирования, Ρ‚ΠΎ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΎΠ±ΡŠΡΠ²ΠΈΡ‚ΡŒ ΠΊΠ°ΠΊ ΠΎΠ±ΠΎΠ±Ρ‰Π΅Π½Π½Ρ‹ΠΉ конструктор копирования, Ρ‚Π°ΠΊ ΠΈ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ. Π’ΠΎ ΠΆΠ΅ касаСтся присваивания. ΠŸΡ€ΠΈΠ²Π΅Π΄Π΅ΠΌ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ опрСдСлСния класса tr1::shared_ptr, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΠ»Π»ΡŽΡΡ‚Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ это ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅: