අධි බර පැටවීමට පොදු ක්රියාකරුවන්
වැඩිපුර පැටවීමේ ක්රියාකරුවන්ගේ බොහෝ කාර්යයන් බොයිලර් තහඩු කේතයයි. එය පුදුමයක් නොවේ, ක්රියාකරුවන් හුදෙක් සින්ටැක්ටික් සීනි බැවින් ඔවුන්ගේ සැබෑ වැඩ කටයුතු සරල කාර්යයන් මගින් (බොහෝ විට යොමු කරනු ලැබේ). නමුත් ඔබ මෙම බොයිලේරු තහඩු කේතය නිවැරදිව ලබා ගැනීම වැදගත්ය. ඔබ අසමත් වුවහොත්, එක්කෝ ඔබේ ක්රියාකරුගේ කේතය සම්පාදනය නොවනු ඇත හෝ ඔබේ පරිශීලකයන්ගේ කේතය සම්පාදනය නොකරනු ඇත හෝ ඔබේ පරිශීලකයන්ගේ කේතය පුදුම සහගත ලෙස හැසිරෙනු ඇත.
පැවරුම් ක්රියාකරු
පැවරුම ගැන බොහෝ දේ කියන්නට ඇත. කෙසේ වෙතත්, බොහෝමයක් දැනටමත් GMan හි සුප්රසිද්ධ පිටපත්-හා- හුවමාරු නිති අසන ප්රශ්නවල පවසා ඇත , එබැවින් මම මෙහි බොහෝ දේ මඟ හරිමි, යොමු කිරීම සඳහා පරිපූර්ණ පැවරුම් ක්රියාකරු ලැයිස්තුගත කිරීම පමණි:
X& X::operator=(X rhs)
{
swap(rhs);
return *this;
}
Bitshift Operators (ධාරාව I / O සඳහා භාවිතා කරයි)
බිට්ෂිෆ්ට් ක්රියාකරුවන් <<
සහ >>
, සී වෙතින් උරුම වන බිට්-හැසිරවීමේ කාර්යයන් සඳහා දෘඩාංග අතුරුමුහුණත් සඳහා තවමත් භාවිතා කර ඇතත්, බොහෝ යෙදුම්වල අධික ලෙස පටවන ලද ධාරා ආදානය සහ ප්රතිදාන ක්රියාකරුවන් ලෙස වඩාත් ප්රචලිත වී ඇත. බිටු-හැසිරවීමේ ක්රියාකරුවන් ලෙස මඟ පෙන්වීම අධික ලෙස පැටවීම සඳහා, ද්විමය අංක ගණිත ක්රියාකරුවන්ගේ පහත කොටස බලන්න. ඔබේ වස්තුව අයෝස්ට්රීම් සමඟ භාවිතා කරන විට ඔබේ අභිරුචි ආකෘතිය ක්රියාත්මක කිරීම සහ තර්කනය විග්රහ කිරීම සඳහා, දිගටම කරගෙන යන්න.
ධාරා ක්රියාකරුවන්, වැඩිපුරම පටවා ඇති ක්රියාකරුවන් අතර ද්විමය ඉන්ෆික්ස් ක්රියාකරුවන් වන අතර ඒ සඳහා සින්ටැක්ස් මඟින් සාමාජිකයන් හෝ සාමාජිකයන් විය යුතුද යන්නට කිසිදු සීමාවක් නොමැත. ඔවුන් ඔවුන්ගේ වම් තර්කය වෙනස් කරන හෙයින් (ඔවුන් ධාරාවේ තත්වය වෙනස් කරයි), මාපට ඇඟිල්ලේ නියමයන්ට අනුව, ඔවුන්ගේ වම් ඔපෙරන්ඩ් වර්ගයේ සාමාජිකයන් ලෙස ක්රියාත්මක කළ යුතුය. කෙසේ වෙතත්, ඔවුන්ගේ වම් ක්රියාකාරිත්වය සම්මත පුස්තකාලයේ ධාරා වන අතර, සම්මත පුස්තකාලය මගින් අර්ථ දක්වා ඇති බොහෝ ධාරා ප්රතිදානය සහ ආදාන ක්රියාකරුවන් සැබවින්ම ධාරා පන්තිවල සාමාජිකයන් ලෙස අර්ථ දක්වා ඇති අතර, ඔබ ඔබේම වර්ග සඳහා ප්රතිදාන සහ ආදාන මෙහෙයුම් ක්රියාත්මක කරන විට, ඔබ සම්මත පුස්තකාලයේ ප්රවාහ වර්ග වෙනස් කළ නොහැක. සාමාජික නොවන කාර්යයන් ලෙස ඔබේම වර්ග සඳහා මෙම ක්රියාකරුවන් ක්රියාත්මක කිරීමට අවශ්ය වන්නේ එබැවිනි. දෙකෙහි කැනොනිකල් ආකාර මේවා ය:
std::ostream& operator<<(std::ostream& os, const T& obj)
{
// write obj to stream
return os;
}
std::istream& operator>>(std::istream& is, T& obj)
{
// read obj from stream
if( /* no valid object of T found in stream */ )
is.setstate(std::ios::failbit);
return is;
}
ක්රියාත්මක කිරීමේදී operator>>
, ප්රවාහයේ තත්වය අතින් සැකසීම අවශ්ය වන්නේ කියවීම සාර්ථක වූ විට පමණි, නමුත් ප්රති result ලය බලාපොරොත්තු වන දෙය නොවේ.
ක්රියාකාරී ඇමතුම් ක්රියාකරු
ශ්රිත වස්තු නිර්මාණය කිරීම සඳහා භාවිතා කරන ශ්රිත ඇමතුම් ක්රියාකරු, ෆන්ක්ටර්ස් ලෙසද හැඳින්වේ, එය සාමාජික ශ්රිතයක් ලෙස අර්ථ දැක්විය යුතුය , එබැවින් එය සැමවිටම this
සාමාජික ශ්රිතයන්ගේ ව්යංග තර්කය ඇත. මේ හැරුණු විට, ශුන්යය ඇතුළුව ඕනෑම අමතර තර්ක ගණනාවක් ගැනීමට එය අධික ලෙස පැටවිය හැකිය.
සින්ටැක්ස් සඳහා උදාහරණයක් මෙන්න:
class foo {
public:
// Overloaded call operator
int operator()(const std::string& y) {
// ...
}
};
භාවිතය:
foo f;
int a = f("hello");
C ++ සම්මත පුස්තකාලය පුරා, ක්රියාකාරී වස්තු සෑම විටම පිටපත් කරනු ලැබේ. එබැවින් ඔබේම ක්රියාකාරී වස්තු පිටපත් කිරීමට ලාභදායී විය යුතුය. ශ්රිත වස්තුවකට පිටපත් කිරීම සඳහා මිල අධික දත්ත භාවිතා කිරීමට අවශ්ය නම්, එම දත්ත වෙනත් තැනක ගබඩා කර තැබීම වඩා හොඳය.
සංසන්දනය කරන්නන්
ද්විමය infix සංසන්දනය ක්රියාකරුවන්, අතේ මාපට ඇඟිල්ල නීති රීති අනුව, සාමාජික නොවන කාර්යයන් ලෙස ක්රියාත්මක කළ යුතු 1 . ඒකීය උපසර්ගය ප්රතික්ෂේප කිරීම !
(එකම නීතිරීතිවලට අනුව) සාමාජික ශ්රිතයක් ලෙස ක්රියාත්මක කළ යුතුය. (නමුත් සාමාන්යයෙන් එය අධික ලෙස පැටවීම හොඳ අදහසක් නොවේ.)
සම්මත පුස්තකාලයේ ඇල්ගොරිතම (උදා std::sort()
) සහ වර්ග (උදා std::map
) සැමවිටම පවතිනු ඇතැයි අපේක්ෂා operator<
කරයි. කෙසේ වෙතත්, ඔබේ වර්ගයේ පරිශීලකයින් අනෙක් සියලුම ක්රියාකරුවන් ද පැමිණෙනු ඇතැයි අපේක්ෂා කරනු ඇත , එබැවින් ඔබ නිර්වචනය කරන්නේ නම් operator<
, ක්රියාකරු අධි බර පැටවීමේ තුන්වන මූලික රීතිය අනුගමනය කිරීමට වග බලා ගන්න සහ අනෙක් සියලුම බූලියන් සංසන්දනාත්මක ක්රියාකරුවන් නිර්වචනය කරන්න. ඒවා ක්රියාත්මක කිරීමට කැනොනිකල් ක්රමය මෙයයි:
inline bool operator==(const X& lhs, const X& rhs){ /* do actual comparison */ }
inline bool operator!=(const X& lhs, const X& rhs){return !operator==(lhs,rhs);}
inline bool operator< (const X& lhs, const X& rhs){ /* do actual comparison */ }
inline bool operator> (const X& lhs, const X& rhs){return operator< (rhs,lhs);}
inline bool operator<=(const X& lhs, const X& rhs){return !operator> (lhs,rhs);}
inline bool operator>=(const X& lhs, const X& rhs){return !operator< (lhs,rhs);}
මෙහිදී සැලකිල්ලට ගත යුතු වැදගත්ම දෙය නම්, මෙම ක්රියාකරුවන්ගෙන් දෙදෙනෙකු පමණක් ඇත්ත වශයෙන්ම යමක් කරන අතර අනෙක් අය සත්ය තර්ක කිරීම සඳහා මේ දෙකෙන් එකක් වෙත ඔවුන්ගේ තර්ක ඉදිරිපත් කිරීමයි.
ඉතිරි ද්විමය බූලියන් ක්රියාකරුවන් ( ||
, &&
) අධික ලෙස පැටවීම සඳහා වන වාක්ය ඛණ්ඩය සංසන්දනාත්මක ක්රියාකරුවන්ගේ නීති රීති අනුගමනය කරයි. කෙසේ වෙතත්, එය ඉතා ඔබ මේ සඳහා සාධාරණ භාවිතය නඩුව සොයා බව නොහැක්කකි 2 .
1 මාපට ඇඟිල්ලේ සියලු නීති මෙන්ම, සමහර විට මෙය බිඳ දැමීමටද හේතු තිබිය හැක. එසේ නම්, සාමාජික සඳහා කටයුතු වනු ඇත, ද්විමය සංසන්දනය ක්රියාකරුවන් වම් අත යන අගයද බව අමතක කරන්න එපා *this
, විය යුතු const
ද,. එබැවින් සාමාජික ශ්රිතයක් ලෙස ක්රියාත්මක කරන සංසන්දනාත්මක ක්රියාකරුවෙකුට මෙම අත්සන තිබිය යුතුය:
bool operator<(const X& rhs) const { /* do actual comparison with *this */ }
( const
අවසානයේ සටහන් කරන්න.)
2 කෙටිමං අර්ථකථනවල සාදන ලද අනුවාදය ||
සහ &&
භාවිතා කරන බව සැලකිල්ලට ගත යුතුය . පරිශීලකයා අර්ථ දක්වා ඇති ඒවා (ඒවා ක්රම ඇමතුම් සඳහා සින්ටැක්ටික් සීනි බැවින්) කෙටිමං අර්ථකථන භාවිතා නොකරයි. පරිශීලකයා මෙම ක්රියාකරුවන්ට කෙටිමං අර්ථකථන ලබා දෙනු ඇතැයි අපේක්ෂා කරන අතර ඔවුන්ගේ කේතය එය මත රඳා පවතී, එබැවින් ඒවා නිර්වචනය කිරීමට කිසි විටෙකත් උපදෙස් දෙනු නොලැබේ.
අංක ගණිත ක්රියාකරුවන්
ඒකීය ගණිත ක්රියාකරුවන්
ඒකීය වර්ධක හා අඩුවීමේ ක්රියාකරුවන් උපසර්ගය සහ පසු සැකසුම් රසය යන දෙකෙන්ම පැමිණේ. එකක් අනෙකාට පැවසීමට නම්, පෝස්ට්ෆික්ස් ප්රභේද අතිරේක ව්යාජ int තර්කයක් ගනී. ඔබ වැඩිපුර පැටවීම හෝ අඩුවීම නම්, සෑම විටම උපසර්ගය සහ පෝස්ට්ෆික්ස් අනුවාද දෙකම ක්රියාත්මක කිරීමට වග බලා ගන්න. වර්ධකයේ කැනොනිකල් ක්රියාත්මක කිරීම මෙන්න, අඩුවීම එකම නීති අනුගමනය කරයි:
class X {
X& operator++()
{
// do actual increment
return *this;
}
X operator++(int)
{
X tmp(*this);
operator++();
return tmp;
}
};
පෝස්ට්ෆික්ස් ප්රභේදය උපසර්ගය අනුව ක්රියාත්මක වන බව සලකන්න. පෝස්ට්ෆික්ස් අතිරේක පිටපතක් කරන බව සලකන්න. 2
ඒකීය us ණ සහ ප්ලස් අධික ලෙස පැටවීම එතරම් සුලභ නොවන අතර බොහෝ විට වළක්වා ගත හැකිය. අවශ්ය නම්, ඒවා බොහෝ විට සාමාජික කාර්යයන් ලෙස පැටවිය යුතුය.
2 තවද, postfix ප්රභේද්යයක් වැඩි වැඩ කරන්නේ බව කරුණාවෙන් හා ඒ නිසා අඩු කාර්යක්ෂම භාවිතා කිරීමේ උපසර්ගය ප්රභේද්යයක් වඩා. සාමාන්යයෙන් පෝස්ට්ෆික්ස් වර්ධකයට වඩා උපසර්ග වර්ධක වලට වැඩි කැමැත්තක් දැක්වීමට මෙය හොඳ හේතුවකි. සම්පාදකයින්ට සාමාන්යයෙන් බිල්ට් වර්ග සඳහා පෝස්ට්ෆික්ස් වර්ධකයේ අමතර කාර්යයන් ප්රශස්තිකරණය කළ හැකි නමුත්, පරිශීලක අර්ථ දක්වන ලද වර්ග සඳහා ඔවුන්ට එයම කළ නොහැකි වනු ඇත (එය ලැයිස්තු අනුකාරකයක් ලෙස අහිංසක ලෙස පෙනෙන දෙයක් විය හැකිය). ඔබ පුරුදු වූ පසු i++
, ගොඩනංවන ලද වර්ගයක් නොමැති ++i
විට ඒ වෙනුවට මතක තබා ගැනීම ඉතා අපහසු වේ i
(ප්ලස් වර්ගයක් වෙනස් කිරීමේදී ඔබට කේතය වෙනස් කළ යුතුය), එබැවින් සෑම විටම පුරුද්දක් කර ගැනීම වඩා හොඳය. පෝස්ට්ෆික්ස් පැහැදිලිවම අවශ්ය නොවන්නේ නම් උපසර්ග වර්ධක භාවිතා කිරීම.
ද්විමය අංක ගණිත ක්රියාකරුවන්
ද්විමය අංක ගණිත ක්රියාකරුවන් සඳහා, තෙවන මූලික රීති ක්රියාකරුගේ බර පැටවීමට කීකරු වීමට අමතක නොකරන්න: ඔබ සපයන්නේ නම් +
, සපයන්නේ +=
නම් -
, අතහරින්න එපා -=
. ආදිය. සංයෝග පැවරුම නිරීක්ෂණය කළ ප්රථමයා ඇන්ඩ rew කොයිනිග් බව කියනු ලැබේ. ක්රියාකරුවන් ඔවුන්ගේ සංයුක්ත නොවන සගයන් සඳහා පදනමක් ලෙස භාවිතා කළ හැකිය. , ක්රියාකරු බව +
අනුව ක්රියාත්මක +=
, -
කොන්දේසි ක්රියාත්මක -=
ආදිය
අපගේ නියමානුකූල නියමයන්ට අනුව, +
සහ එහි සගයන් සාමාජිකයන් නොවන අතර ඔවුන්ගේ සංයුක්ත පැවරුම් සගයන් ( +=
යනාදිය) ඔවුන්ගේ වම් තර්කය වෙනස් කරමින් සාමාජිකයෙකු විය යුතුය. +=
සහ සඳහා ආදර්ශමත් කේතය මෙන්න +
; අනෙක් ද්විමය ගණිත ක්රියාකරුවන් එකම ආකාරයකින් ක්රියාත්මක කළ යුතුය:
class X {
X& operator+=(const X& rhs)
{
// actual addition of rhs to *this
return *this;
}
};
inline X operator+(X lhs, const X& rhs)
{
lhs += rhs;
return lhs;
}
operator+=
එහි ප්රති result ලය යොමු operator+
කිරීමකට ලබා දෙන අතර එහි ප්රති .ලයේ පිටපතක් ලබා දෙයි. ඇත්ත වශයෙන්ම, යොමු කිරීමක් ආපසු යැවීම සාමාන්යයෙන් පිටපතක් ආපසු ලබා දීමට වඩා කාර්යක්ෂම වේ, නමුත් එසේ නම් operator+
, පිටපත් කිරීම සඳහා වෙනත් ක්රමයක් නොමැත. ඔබ ලියන විට a + b
, ප්රති result ලය නව අගයක් වනු ඇතැයි ඔබ අපේක්ෂා කරයි, එබැවින් operator+
නව අගයක් ආපසු ලබා දිය යුතුය. 3operator+
එහි වම් ක්රියාකාරිත්වය සංයුක්ත යොමු කිරීමකට වඩා පිටපතක් මගින් ගන්නා
බව සලකන්න . මෙයට හේතුව operator=
එහි පිටපතකට එහි තර්කය ගැනීමට හේතුවයි .
බිටු හැසිරවීමේ ක්රියාකරුවන් ~
&
|
^
<<
>>
ගණිතමය ක්රියාකරුවන් මෙන් ක්රියාත්මක කළ යුතුය. කෙසේ වෙතත්, (අධි බර පැටවීම <<
සහ >>
ප්රතිදානය සහ ආදානය හැර) මේවා අධික ලෙස පැටවීම සඳහා සාධාරණ භාවිත අවස්ථා ඉතා අල්පය.
3 නැවතත්, මෙම සිට ගත යුතු පාඩම වන්නේ a += b
වඩා කාර්යක්ෂම, සාමාන්යයෙන්, ය a + b
හැකි නම් කැමති විය යුතුය.
අරා දායකත්වය
අරාව ග්රාහක ක්රියාකරු යනු ද්විමය ක්රියාකරු වන අතර එය පන්ති සාමාජිකයෙකු ලෙස ක්රියාත්මක කළ යුතුය. යතුරකින් ඒවායේ දත්ත මූලද්රව්ය වෙත ප්රවේශ වීමට ඉඩ සලසන බහාලුම් වැනි වර්ග සඳහා එය භාවිතා කරයි. මේවා සැපයීමේ කැනොනිකල් ස්වරූපය මෙයයි:
class X {
value_type& operator[](index_type idx);
const value_type& operator[](index_type idx) const;
// ...
};
ඔබේ පන්තියේ පරිශීලකයින්ට ආපසු ලබා දෙන දත්ත මූලද්රව්ය වෙනස් කිරීමට ඔබට අවශ්ය නොවන්නේ නම් operator[]
(ඔබට නොනවතින ප්රභේදය මඟ හැරිය හැක), ඔබ සැමවිටම ක්රියාකරුගේ ප්රභේද දෙකම ලබා දිය යුතුය.
Value_type යනු සාදන ලද වර්ගයකට යොමු වීමට දන්නා නම්, ක්රියාකරුගේ සංයුක්ත ප්රභේදය සංයුක්ත යොමු කිරීමක් වෙනුවට පිටපතක් ආපසු ලබා දිය යුතුය:
class X {
value_type& operator[](index_type idx);
value_type operator[](index_type idx) const;
// ...
};
පොයින්ටර් වැනි වර්ග සඳහා ක්රියාකරුවන්
ඔබේම අනුකාරක හෝ ස්මාර්ට් *
පොයින්ටර්ස් නිර්වචනය කිරීම සඳහා, ඔබට ඒකීය උපසර්ග විරූපණ ක්රියාකරු සහ ද්විමය ඉන්ෆික්ස් පොයින්ටර් සාමාජික ප්රවේශ ක්රියාකරු අධික ලෙස පැටවිය යුතුය ->
:
class my_ptr {
value_type& operator*();
const value_type& operator*() const;
value_type* operator->();
const value_type* operator->() const;
};
මේවාට ද සෑම විටම පාහේ const සහ non non const අනුවාදයක් අවශ්ය බව සලකන්න. සඳහා ->
ක්රියාකරු, නම් value_type
වේ class
(හෝ struct
හෝ union
වර්ගය), තවත් operator->()
ඇත්තෙන් වෙනසට භාජනය, ක දක්වා හැඳින්වේ operator->()
පන්තියේ නොවන වර්ගයේ අගය පැමිණේ.
ක්රියාකරුගේ අවිධිමත් ලිපිනය කිසි විටෙකත් අධික ලෙස පැටවිය යුතු නොවේ.
සඳහා operator->*()
බලන්න මේ ප්රශ්නය . එය කලාතුරකින් භාවිතා වන අතර කලාතුරකින් අධික ලෙස පටවනු ලැබේ. ඇත්ත වශයෙන්ම, අනුකාරක පවා එය අධික ලෙස පටවන්නේ නැත.
පරිවර්තන ක්රියාකරුවන් වෙත දිගටම යන්න