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

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

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

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


template<class T> class shared_ptr {

public:

shared_ptr(shared_ptr const& r); // конструктор копирования

template<class Y> // ΠΎΠ±ΠΎΠ±Ρ‰Π΅Π½Π½Ρ‹ΠΉ

shared_ptr(shared_ptr<Y> const& r); // конструктор копирования

shared_ptr& operator=(shared_ptr const& r); // ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ присваивания

template<class Y> // ΠΎΠ±ΠΎΠ±Ρ‰Π΅Π½Π½Ρ‹ΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€

shared_ptr& operator=(shared_ptr<Y> const& r); // присваивания

...

};


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

β€’ Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ΡˆΠ°Π±Π»ΠΎΠ½Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Ρ‹ для Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰ΠΈΡ… всС совмСстимыС Ρ‚ΠΈΠΏΡ‹.

β€’ Если Π²Ρ‹ ΠΎΠ±ΡŠΡΠ²Π»ΡΠ΅Ρ‚Π΅ ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹ ΠΎΠ±ΠΎΠ±Ρ‰Π΅Π½Π½Ρ‹Ρ… конструкторов копирования ΠΈΠ»ΠΈ ΠΎΠ±ΠΎΠ±Ρ‰Π΅Π½Π½ΠΎΠ³ΠΎ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° присваивания, Ρ‚ΠΎ ΠΏΠΎ-ΠΏΡ€Π΅ΠΆΠ½Π΅ΠΌΡƒ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΎΠ±ΡŠΡΠ²ΠΈΡ‚ΡŒ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ конструктор копирования ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ присваивания.

ΠŸΡ€Π°Π²ΠΈΠ»ΠΎ 46: ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΠΉΡ‚Π΅ Π²Π½ΡƒΡ‚Ρ€ΠΈ шаблонов Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π½Π΅ ΡΠ²Π»ΡΡŽΡ‰ΠΈΠ΅ΡΡ Ρ‡Π»Π΅Π½Π°ΠΌΠΈ, ΠΊΠΎΠ³Π΄Π° ΠΆΠ΅Π»Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ прСобразования Ρ‚ΠΈΠΏΠ°

Π’ ΠΏΡ€Π°Π²ΠΈΠ»Π΅ 24 ΠΎΠ±ΡŠΡΡΠ½ΡΠ΅Ρ‚ΡΡ, ΠΏΠΎΡ‡Π΅ΠΌΡƒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊ свободным функциям ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ нСявныС прСобразования Ρ‚ΠΈΠΏΠΎΠ² всСх Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ². Π’ качСствС ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Π±Ρ‹Π»Π° ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° функция operator* для класса Rational. ΠŸΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚ΡŒ Ρ‡Ρ‚Π΅Π½ΠΈΠ΅, Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΡŽ Π²Π°ΠΌ ΠΎΡΠ²Π΅ΠΆΠΈΡ‚ΡŒ этот ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π² памяти, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ сСйчас ΠΌΡ‹ вСрнСмся ΠΊ этой Ρ‚Π΅ΠΌΠ΅, рассмотрСв Π±Π΅Π·ΠΎΠ±ΠΈΠ΄Π½Ρ‹Π΅, Π½Π° ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ взгляд, ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° ΠΈΠ· ΠΏΡ€Π°Π²ΠΈΠ»Π° 24. ΠžΡ‚Π»ΠΈΡ‡ΠΈΠ΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΈ класс Rational, ΠΈ operator* Π² Π½Π΅ΠΌ сдСланы шаблонами:


template <typename T>

class Rational {

public:

Rational(const T& numerator = 0, // см. Π² ΠΏΡ€Π°Π²ΠΈΠ»Π΅ 20 – ΠΏΠΎΡ‡Π΅ΠΌΡƒ

const T& denominator = 1); // ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ пСрСдаСтся ΠΏΠΎ ссылкС

const T numerator() const; // см. Π² ΠΏΡ€Π°Π²ΠΈΠ»Π΅ 28 – ΠΏΠΎΡ‡Π΅ΠΌΡƒ

const T denominator() const; // Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ возвращаСтся ΠΏΠΎ

... // Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ, Π° Π² ΠΏΡ€Π°Π²ΠΈΠ»Π΅ 3 –

// ΠΏΠΎΡ‡Π΅ΠΌΡƒ ΠΎΠ½ΠΈ константны

};

template <typename T>

const Rational<T> operator*(const Rational<T>& lhs,

const Rational<T>& rhs)

{...}


Как ΠΈ Π² ΠΏΡ€Π°Π²ΠΈΠ»Π΅ 24, ΠΌΡ‹ собираСмся ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ ΡΠΌΠ΅ΡˆΠ°Π½Π½ΡƒΡŽ Π°Ρ€ΠΈΡ„ΠΌΠ΅Ρ‚ΠΈΠΊΡƒ, поэтому Ρ…ΠΎΡ‚Π΅Π»ΠΎΡΡŒ Π±Ρ‹, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹ΠΉ Π½ΠΈΠΆΠ΅ ΠΊΠΎΠ΄ компилировался. ΠœΡ‹ Π½Π΅ ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌ ΠΏΠΎΠ΄Π²ΠΎΡ…ΠΎΠ², ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ Π² ΠΏΡ€Π°Π²ΠΈΠ»Π΅ 24 Ρ€Π°Π±ΠΎΡ‚Π°Π». ЕдинствСнноС ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ класс Rational ΠΈ функция-Ρ‡Π»Π΅Π½ operator* Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹:


Raional<int> oneHalf(1, 2); // это ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΈΠ· ΠΏΡ€Π°Π²ΠΈΠ»Π° 24,

// Π½ΠΎ Rational – Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ шаблон

Ratinal<int> result = oneHalf * 2; // ошибка! НС компилируСтся


Π’ΠΎΡ‚ Ρ„Π°ΠΊΡ‚, Ρ‡Ρ‚ΠΎ этот ΠΊΠΎΠ΄ Π½Π΅ компилируСтся, Π½Π°Π²ΠΎΠ΄ΠΈΡ‚ Π½Π° ΠΌΡ‹ΡΠ»ΡŒ, Ρ‡Ρ‚ΠΎ Π² шаблонС Rational Π΅ΡΡ‚ΡŒ Π½Π΅Ρ‡Ρ‚ΠΎ, ΠΎΡ‚Π»ΠΈΡ‡Π°ΡŽΡ‰Π΅Π΅ Π΅Π³ΠΎ ΠΎΡ‚ нСшаблонной вСрсии. И это Π½Π° самом Π΄Π΅Π»Π΅ Ρ‚Π°ΠΊ. Π’ ΠΏΡ€Π°Π²ΠΈΠ»Π΅ 24 компилятор Π·Π½Π°Π», ΠΊΠ°ΠΊΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΌΡ‹ пытаСмся Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ (operator*, ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰ΡƒΡŽ Π΄Π²Π° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° Ρ‚ΠΈΠΏΠ° Rational), здСсь ΠΆΠ΅ Π΅ΠΌΡƒ ΠΎΠ± этом Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ извСстно. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ компилятор пытаСтся Ρ€Π΅ΡˆΠΈΡ‚ΡŒ, ΠΊΠ°ΠΊΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Π½ΡƒΠΆΠ½ΠΎ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ (Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ) ΠΈΠ· шаблона operator*. Он Π·Π½Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ имя этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ operator* ΠΈ ΠΎΠ½Π° ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π΄Π²Π° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° Ρ‚ΠΈΠΏΠ° Rational<T>, Π½ΠΎ для Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎΠ±Ρ‹ произвСсти ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚ΠΈΠ·Π°Ρ†ΠΈΡŽ, Π½ΡƒΠΆΠ½ΠΎ Π²Ρ‹ΡΡΠ½ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ T. ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ компилятор Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ этого ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ.

ΠŸΡ‹Ρ‚Π°ΡΡΡŒ вывСсти T, компилятор смотрит Π½Π° Ρ‚ΠΈΠΏΡ‹ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ², ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ operator*. Π’ Π΄Π°Π½Π½ΠΎΠΌ случаС это Rational<int> (Ρ‚ΠΈΠΏ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ oneHalf) ΠΈ int (Ρ‚ΠΈΠΏ Π»ΠΈΡ‚Π΅Ρ€Π°Π»Π° 2). ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ рассматриваСтся ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ.

Π’Ρ‹Π²ΠΎΠ΄ Π½Π° основС Ρ‚ΠΈΠΏΠ° oneHalf ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π»Π΅Π³ΠΊΠΎ. ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ operator* объявлСн ΠΊΠ°ΠΊ Rational<T>, Π° ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚, ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹ΠΉ operator* (oneHalf), ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚ΠΈΠΏ Rational<int>, поэтому T Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ int. К соТалСнию, вывСсти Ρ‚ΠΈΠΏ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° Π½Π΅ Ρ‚Π°ΠΊ просто. Из объявлСния извСстно, Ρ‡Ρ‚ΠΎ Ρ‚ΠΈΠΏ Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° operator* Ρ€Π°Π²Π΅Π½ Rational<T>, Π½ΠΎ Π²Ρ‚ΠΎΡ€ΠΎΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚, ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹ΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ operator* (число 2), ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚ΠΈΠΏ int. Как компилятору ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ T Π² Π΄Π°Π½Π½ΠΎΠΌ случаС? МоТно ΠΎΠΆΠΈΠ΄Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ‚ΡΡ Π½Π΅-explicit конструктором, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Ρ‚ΡŒ 2 Π² Rational<int> ΠΈ Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π²Ρ‹Π²ΠΎΠ΄, Ρ‡Ρ‚ΠΎ T Π΅ΡΡ‚ΡŒ int, Π½ΠΎ Π½Π° Π΄Π΅Π»Π΅ этого Π½Π΅ происходит. ΠšΠΎΠΌΠΏΠΈΠ»ΡΡ‚ΠΎΡ€ Π½Π΅ поступаСт Ρ‚Π°ΠΊ ΠΏΠΎΡ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ нСявного прСобразования Ρ‚ΠΈΠΏΠ° Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°ΡŽΡ‚ΡΡ ΠΏΡ€ΠΈ Π²Ρ‹Π²ΠΎΠ΄Π΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² шаблона. Никогда. Π”Π°, Ρ‚Π°ΠΊΠΈΠ΅ прСобразования ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π°Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, Π½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄ Ρ‚Π΅ΠΌ, ΠΊΠ°ΠΊ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, Π½ΡƒΠΆΠ½ΠΎ ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ ΠΎΠ½Π° ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚. Π§Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ Π² этом, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ вывСсти Ρ‚ΠΈΠΏΡ‹ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² для всСх ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎ подходящих шаблонов Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ (Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ). Но нСявныС прСобразования Ρ‚ΠΈΠΏΠΎΠ² посрСдством Π²Ρ‹Π·ΠΎΠ²Π° конструкторов ΠΏΡ€ΠΈ Π²Ρ‹Π²ΠΎΠ΄Π΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² шаблона Π½Π΅ Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°ΡŽΡ‚ΡΡ. Π’ ΠΏΡ€Π°Π²ΠΈΠ»Π΅ 24 Π½ΠΈΠΊΠ°ΠΊΠΈΡ… шаблонов Π½Π΅ Π±Ρ‹Π»ΠΎ, поэтому ΠΈ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π²Ρ‹Π²ΠΎΠ΄Π° Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² шаблона Π½Π΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π»Π°. Π—Π΄Π΅ΡΡŒ ΠΆΠ΅ ΠΌΡ‹ ΠΈΠΌΠ΅Π΅ΠΌ Π΄Π΅Π»ΠΎ с шаблонной Ρ‡Π°ΡΡ‚ΡŒΡŽ C++ (см. ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ 1), ΠΈ ΠΎΠ½Π° Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΡ‚ Π½Π° ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΏΠ»Π°Π½.

ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠΌΠΎΡ‡ΡŒ компилятору Π² Π²Ρ‹Π²ΠΎΠ΄Π΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² шаблона, воспользовавшись объявлСниСм друТСствСнной Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π² шаблонном классС. Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ класс Rational<T> ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΠ±ΡŠΡΠ²ΠΈΡ‚ΡŒ operator* для Rational<T> ΠΊΠ°ΠΊ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ-Π΄Ρ€ΡƒΠ³Π°. К шаблонам классов ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° Π²Ρ‹Π²ΠΎΠ΄Π° Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΡ (ΠΎΠ½Π° примСняСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊ шаблонам Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ), поэтому Ρ‚ΠΈΠΏ T всСгда извСстСн Π² ΠΌΠΎΠΌΠ΅Π½Ρ‚ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚ΠΈΠ·Π°Ρ†ΠΈΠΈ Rational<T>. Π­Ρ‚ΠΎ ΡƒΠΏΡ€ΠΎΡ‰Π°Π΅Ρ‚ объявлСниС ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ operator* ΠΊΠ°ΠΊ Π΄Ρ€ΡƒΠ³Π° класса Rational<T>:


template <typename T>

class Rational {

public:

...

friend // объявлСниС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

const Rational operator*(const Rational& lhs, // operator*

const Rational& rhs); // (подробности см. Π½ΠΈΠΆΠ΅)

};

template <typename T> // ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

const Rational<T> operator*(const Rational<T>& lhs, // operator*

const Rational<T>& rhs)

{...}


Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π²Ρ‹Π·ΠΎΠ²Ρ‹ operator* с Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°ΠΌΠΈ Ρ€Π°Π·Π½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² ΡΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΡƒΡŽΡ‚ΡΡ, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈ объявлСнии ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ oneHalf Ρ‚ΠΈΠΏΠ° Rational<int> конкрСтизируСтся класс Rational<int> ΠΈ Π²ΠΌΠ΅ΡΡ‚Π΅ с Π½ΠΈΠΌ функция-Π΄Ρ€ΡƒΠ³ operator*, которая ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Rational<int>. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ±ΡŠΡΠ²Π»ΡΠ΅Ρ‚ΡΡ функция (Π° Π½Π΅ шаблон Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ), компилятор ΠΌΠΎΠΆΠ΅Ρ‚ для Π²Ρ‹Π²ΠΎΠ΄Π° Ρ‚ΠΈΠΏΠΎΠ² ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ функциями нСявного прСобразования (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π½Π΅-explicit конструкторами Rational) ΠΈ, стало Π±Ρ‹Ρ‚ΡŒ, сумССт Ρ€Π°Π·ΠΎΠ±Ρ€Π°Ρ‚ΡŒΡΡ Π² Π²Ρ‹Π·ΠΎΠ²Π΅ operator* с ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ Ρ€Π°Π·Π½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ².

К соТалСнию, Ρ„Ρ€Π°Π·Π° «сумССт Ρ€Π°Π·ΠΎΠ±Ρ€Π°Ρ‚ΡŒΡΡΒ» Π² Π΄Π°Π½Π½ΠΎΠΌ контСкстС ΠΈΠΌΠ΅Π΅Ρ‚ ироничСский ΠΎΡ‚Ρ‚Π΅Π½ΠΎΠΊ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ хотя ΠΊΠΎΠ΄ ΠΈ компилируСтся, Π½ΠΎ Π½Π΅ компонуСтся. ВскорС ΠΌΡ‹ займСмся этой ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΎΠΉ, Π½ΠΎ сначала я Ρ…ΠΎΡ‡Ρƒ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΎΠ΄Π½ΠΎ Π·Π°ΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅ ΠΎ синтаксисС, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠΌ для объявлСния Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ operator* Π² классС Rational.

Π’Π½ΡƒΡ‚Ρ€ΠΈ шаблона класса имя шаблона ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ сокращСнноС ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ шаблона вмСстС с ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ, поэтому Π²Π½ΡƒΡ‚Ρ€ΠΈ Ratonal<T> Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅Ρ‚ΡΡ ΠΏΠΈΡΠ°Ρ‚ΡŒ просто Rational вмСсто Ratonal<T>. Π’ Π΄Π°Π½Π½ΠΎΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ это экономит лишь нСсколько символов, Π½ΠΎ ΠΊΠΎΠ³Π΄Π° Π΅ΡΡ‚ΡŒ нСсколько ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² с Π΄Π»ΠΈΠ½Π½Ρ‹ΠΌΠΈ ΠΈΠΌΠ΅Π½Π°ΠΌΠΈ, это ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΡ‚ΡŒ Ρ€Π°Π·ΠΌΠ΅Ρ€ исходного ΠΊΠΎΠ΄Π° ΠΈ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π΅Π³ΠΎ яснСС. Π― вспомнил ΠΎΠ± этом, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ operator* объявлСн ΠΊΠ°ΠΊ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰ΠΈΠΉ ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‰ΠΈΠΉ Rational вмСсто Rational<T>. Π’Π°ΠΊΠΆΠ΅ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ Π±Ρ‹Π»ΠΎ Π±Ρ‹ ΠΎΠ±ΡŠΡΠ²ΠΈΡ‚ΡŒ operator* ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:


template <typename T>

class Rational {

public:

...

friend

const Rational<T> operator*(const Rational<T>& lhs,

const Rational<T>& rhs);

...

};


Однако ΠΏΡ€ΠΎΡ‰Π΅ (ΠΈ часто Ρ‚Π°ΠΊ ΠΈ дСлаСтся) ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡΠΎΠΊΡ€Π°Ρ‰Π΅Π½Π½ΡƒΡŽ Ρ„ΠΎΡ€ΠΌΡƒ.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ вСрнСмся ΠΊ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½ΠΎΠ²ΠΊΠΈ. Код, содСрТащий Π²Ρ‹Π·ΠΎΠ² с ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ², компилируСтся, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ компилятор Π·Π½Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Π²ΠΏΠΎΠ»Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ (operator*, ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰ΡƒΡŽ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Ρ‚ΠΈΠΏΠ° Rational<int> ΠΈ Rational<int>), Π½ΠΎ эта функция Ρ‚ΠΎΠ»ΡŒΠΊΠΎ объявлСна Π²Π½ΡƒΡ‚Ρ€ΠΈ Rational, Π½ΠΎ Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π° Ρ‚Π°ΠΌ. Наша Ρ†Π΅Π»ΡŒ – Π·Π°ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ шаблон Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ operator*, Π½Π΅ ΡΠ²Π»ΡΡŽΡ‰Π΅ΠΉΡΡ Ρ‡Π»Π΅Π½ΠΎΠΌ класса, ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ это ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅, Π½ΠΎ Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ Π΅Π΅ Π½Π΅ Π΄ΠΎΡΡ‚ΠΈΡ‡ΡŒ. Если ΠΌΡ‹ объявляСм Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ (Π° Ρ‚Π°ΠΊ ΠΈ происходит, ΠΊΠΎΠ³Π΄Π° ΠΎΠ½Π° находится Π²Π½ΡƒΡ‚Ρ€ΠΈ шаблона Rational), Ρ‚ΠΎ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΏΠΎΠ·Π°Π±ΠΎΡ‚ΠΈΡ‚ΡŒΡΡ ΠΈ ΠΎΠ± Π΅Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ. Π’ Π΄Π°Π½Π½ΠΎΠΌ случаС ΠΌΡ‹ Π½ΠΈΠ³Π΄Π΅ Π½Π΅ ΠΏΡ€ΠΈΠ²Π΅Π»ΠΈ опрСдСлСния, поэтому ΠΊΠΎΠΌΠΏΠΎΠ½ΠΎΠ²Ρ‰ΠΈΠΊ Π΅Π³ΠΎ ΠΈ Π½Π΅ Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚.

ΠŸΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠΈΠΉ способ ΠΈΡΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ ΡΠΈΡ‚ΡƒΠ°Ρ†ΠΈΡŽ – ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒ Ρ‚Π΅Π»ΠΎ operator* с Π΅Π³ΠΎ объявлСниСм:


template <typename T>

class Rational {

public:

...

friend Rational operator*(const Rational& lhs, const Rational& rhs)

{

return Rational(lhs.numerator() * rhs.numerator(), // Ρ‚Π° ΠΆΠ΅

lhs.denominator () * rhs.denominator()); // рСализация,

} // Ρ‡Ρ‚ΠΎ ΠΈ

// Π² ΠΏΡ€Π°Π²ΠΈΠ»Π΅ 24

};


НаконСц-Ρ‚ΠΎ всС Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΊΠ°ΠΊ Π½ΡƒΠΆΠ½ΠΎ: Π²Ρ‹Π·ΠΎΠ²Ρ‹ operator* с ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ ΡΠΌΠ΅ΡˆΠ°Π½Π½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΡƒΡŽΡ‚ΡΡ, ΠΊΠΎΠΌΠΏΠΎΠ½ΡƒΡŽΡ‚ΡΡ ΠΈ Π·Π°ΠΏΡƒΡΠΊΠ°ΡŽΡ‚ΡΡ. Π£Ρ€Π°!