පෙරවදන
ජාවා යනු සී ++ වැනි කිසිවක් නොවේ. ජාවා හයිප් යන්ත්රය ඔබ විශ්වාස කිරීමට කැමතියි ජාවා සින්ටැක්ස් වැනි C ++ ඇති බැවින් භාෂා සමාන බව. සත්යයෙන් තවත් කිසිවක් කළ නොහැකිය. මෙම වැරදි තොරතුරු ජාවා ක්රමලේඛකයින් C ++ වෙත ගොස් ඔවුන්ගේ කේතයේ ඇඟවුම් තේරුම් නොගෙන ජාවා වැනි සින්ටැක්ස් භාවිතා කිරීමට හේතුවකි.
ඉදිරියට අපි යමු
නමුත් මට හිතාගන්න බැහැ ඇයි අපි මේ විදියට කරන්නෙ කියලා. මතක ලිපිනයට අපට access ජු ප්රවේශයක් ලැබෙන බැවින් එය කාර්යක්ෂමතාව හා වේගය සමඟ කළ යුතු යැයි මම සිතමි. මම හරිද?
ඊට පටහැනිව, ඇත්ත වශයෙන්ම. ගොඩවල් ගොඩට වඩා මන්දගාමී ය, මන්ද යත් ගොඩට සාපේක්ෂව තොගය ඉතා සරල ය. ස්වයංක්රීය ගබඩා විචල්යයන් (aka stack variable) ඒවායේ විෂය පථයෙන් බැහැර වූ පසු ඒවායේ විනාශ කරන්නන් කැඳවනු ලැබේ. උදාහරණයක් වශයෙන්:
{
std::string s;
}
// s is destroyed here
අනෙක් අතට, ඔබ ගතිකව වෙන් කර ඇති දර්ශකයක් භාවිතා කරන්නේ නම්, එහි විනාශ කරන්නා අතින් කැඳවිය යුතුය. delete
ඔබ වෙනුවෙන් මෙම විනාශ කරන්නා අමතන්න.
{
std::string* s = new std::string;
}
delete s; // destructor called
new
සී # සහ ජාවා වල පවතින සින්ටැක්ස් සමඟ මෙයට කිසිදු සම්බන්ධයක් නැත . ඒවා සම්පූර්ණයෙන්ම වෙනස් අරමුණු සඳහා යොදා ගනී.
ගතික වෙන්කිරීමේ ප්රතිලාභ
1. අරාවෙහි ප්රමාණය ඔබ කල්තියා දැනගත යුතු නැත
බොහෝ සී ++ ක්රමලේඛකයින් මුහුණ දෙන පළමු ගැටලුව නම්, ඔවුන් පරිශීලකයින්ගෙන් අත්තනෝමතික ආදානය භාර ගන්නා විට, ඔබට වෙන් කළ හැක්කේ ස්ථාවර විචල්යයක් සඳහා ස්ථාවර ප්රමාණයක් පමණි. ඔබට අරා වල ප්රමාණයද වෙනස් කළ නොහැක. උදාහරණයක් වශයෙන්:
char buffer[100];
std::cin >> buffer;
// bad input = buffer overflow
ඇත්ත වශයෙන්ම, ඔබ std::string
ඒ වෙනුවට භාවිතා කළේ නම්, std::string
ගැටලුවක් නොවිය යුතු අභ්යන්තරව ප්රමාණය වෙනස් වේ. නමුත් මූලික වශයෙන් මෙම ගැටලුවට විසඳුම ගතික වෙන් කිරීමකි. පරිශීලකයාගේ ආදානය මත පදනම්ව ඔබට ගතික මතකය වෙන් කළ හැකිය, උදාහරණයක් ලෙස:
int * pointer;
std::cout << "How many items do you need?";
std::cin >> n;
pointer = new int[n];
පැති සටහන : බොහෝ ආරම්භකයින් කරන එක් අත්වැරැද්දක් වන්නේ විචල්ය දිග අරා භාවිතා කිරීමයි. මෙය GNU දිගුවක් වන අතර එය ක්ලැන්ග්හි එකක් වන අතර ඒවා GCC හි බොහෝ දිගු පිළිබිඹු කරයි. එබැවින් පහත සඳහන් දෑ
int arr[n]
මත රඳා නොසිටිය යුතුය.
ගොඩවල් තොගයට වඩා විශාල බැවින් කෙනෙකුට අත්තනෝමතික ලෙස ඔහුට / ඇයට අවශ්ය තරම් මතකය වෙන් කළ හැකිය / නැවත වෙන් කළ හැකිය, එහෙත් තොගයට සීමාවක් ඇත.
2. අරා දර්ශකයන් නොවේ
මෙය ඔබ ඉල්ලන ප්රතිලාභයක් වන්නේ කෙසේද? අරා සහ පොයින්ටර් පිටුපස ඇති ව්යාකූලත්වය / මිථ්යාව තේරුම් ගත් පසු පිළිතුර පැහැදිලි වනු ඇත. ඒවා එක හා සමාන යැයි පොදුවේ උපකල්පනය කෙරේ, නමුත් ඒවා එසේ නොවේ. මෙම මිථ්යාව පැමිණෙන්නේ දර්ශකයන් අරා මෙන් දායක විය හැකි නිසා සහ ශ්රිත ප්රකාශනයක ඉහළ මට්ටමේ දර්ශකයන්ට අරා ක්ෂය වීම නිසා ය. කෙසේ වෙතත්, අරාව දර්ශකයකට ක්ෂය වූ පසු, දර්ශකයට එහි sizeof
තොරතුරු නැති වේ . ඒ නිසා sizeof(pointer)
සාමාන්යයෙන් 64-bit පද්ධති මත 8 බයිට් වන, බයිට් වලින් පෙන්නුම් කරන්නක් ප්රමාණය ලබා දෙනු ඇත.
ඔබට අරා වලට පැවරිය නොහැක, ඒවා ආරම්භ කිරීම පමණි. උදාහරණයක් වශයෙන්:
int arr[5] = {1, 2, 3, 4, 5}; // initialization
int arr[] = {1, 2, 3, 4, 5}; // The standard dictates that the size of the array
// be given by the amount of members in the initializer
arr = { 1, 2, 3, 4, 5 }; // ERROR
අනෙක් අතට, ඔබට අවශ්ය ඕනෑම දෙයක් දර්ශකයන් සමඟ කළ හැකිය. අවාසනාවකට මෙන්, දර්ශක සහ අරා අතර වෙනස ජාවා සහ සී # හි අතින් රැළි ඇති හෙයින්, ආරම්භකයින්ට වෙනස තේරෙන්නේ නැත.
3. බහුමාපකය
ජාවා සහ සී # ඔබට වෙනත් වස්තුවක් ලෙස සැලකීමට ඉඩ සලසන පහසුකම් ඇත, උදාහරණයක් ලෙස as
මූල පදය භාවිතා කිරීම . එබැවින් යමෙකුට යම් Entity
වස්තුවක් වස්තුවක් ලෙස සැලකීමට අවශ්ය නම් Player
, කෙනෙකුට එය කළ හැක්කේ Player player = Entity as Player;
ඔබ සමජාතීය බහාලුමක් මත ශ්රිත ඇමතීමට අදහස් කරන්නේ නම් එය විශේෂිත වර්ගයකට පමණක් අදාළ විය යුතුය. පහත දැක්වෙන සමාන ආකාරයකින් ක්රියාකාරීත්වය ලබා ගත හැකිය:
std::vector<Base*> vector;
vector.push_back(&square);
vector.push_back(&triangle);
for (auto& e : vector)
{
auto test = dynamic_cast<Triangle*>(e); // I only care about triangles
if (!test) // not a triangle
e.GenericFunction();
else
e.TriangleOnlyMagic();
}
එබැවින් කියන්න ත්රිකෝණවලට භ්රමණය වන ශ්රිතයක් තිබුනේ නම්, ඔබ එය පන්තියේ සියලුම වස්තු මත ඇමතීමට උත්සාහ කළහොත් එය සම්පාදක දෝෂයක් වනු ඇත. භාවිතා කිරීමෙන් dynamic_cast
, ඔබට as
මූලික පදය අනුකරණය කළ හැකිය . පැහැදිලිව කිවහොත්, වාත්තු කිරීම අසමත් වුවහොත් එය අවලංගු දර්ශකයක් ලබා දෙයි. එබැවින් NULL හෝ අවලංගු දර්ශකයක්ද යන්න !test
පරීක්ෂා කිරීම සඳහා කෙටියෙන් දැක්විය යුතුය test
, එයින් අදහස් වන්නේ වාත්තු කිරීම අසාර්ථක බවයි.
ස්වයංක්රීය විචල්යයන්ගේ ප්රතිලාභ
ගතික ප්රතිපාදන මගින් කළ හැකි සියලු ශ්රේෂ් things දේ දැකීමෙන් පසු, ඔබ සිතන්නේ කිසිවෙකු නිතරම ගතික ප්රතිපාදන භාවිතා නොකරන්නේ මන්ද යන්නයි. මම දැනටමත් ඔබට එක් හේතුවක් පවසා ඇත, ගොඩවල් මන්දගාමී වේ. ඔබට ඒ සියලු මතකය අවශ්ය නොවේ නම්, ඔබ එය අනිසි ලෙස භාවිතා නොකළ යුතුය. එබැවින් විශේෂිත අනුපිළිවෙලක අවාසි කිහිපයක් මෙහි දැක්වේ:
එය දෝෂ සහිත ය. අතින් මතකය වෙන් කිරීම භයානක වන අතර ඔබ කාන්දුවීම් වලට ගොදුරු වේ. නිදොස්කරණය හෝ valgrind
(මතක කාන්දු වන මෙවලමක්) භාවිතා කිරීමට ඔබ ප්රවීණ නොවන්නේ නම් , ඔබේ හිසකෙස් ඔබේ හිසෙන් ඉවතට ගත හැකිය. වාසනාවකට මෙන් RAII මෝඩයන් සහ ස්මාර්ට් පොයින්ටර්ස් මෙය ටිකක් සමනය කරයි, නමුත් ඔබ තුනේ රීතිය සහ පහේ රීතිය වැනි භාවිතයන් ගැන දැන සිටිය යුතුය. එය ගත යුතු තොරතුරු රාශියක් වන අතර, නොදන්නා හෝ ගණන් නොගන්නා ආරම්භකයින් මෙම උගුලට වැටෙනු ඇත.
එය අවශ්ය නොවේ. ජාවා සහ සී # මෙන් නොව new
, සෑම තැනකම යතුරුපදය භාවිතා කිරීම මුග්ධය, සී ++ හි, ඔබ එය භාවිතා කළ යුත්තේ ඔබට අවශ්ය නම් පමණි. පොදු වාක්ය ඛණ්ඩය යන්නේ, ඔබට මිටියක් තිබේ නම් සියල්ල නියපොතු මෙන් පෙනේ. C ++ සමඟ ආරම්භ කරන ආරම්භකයින් දර්ශකයන්ට බිය වන අතර පුරුද්දෙන් සිරස් විචල්යයන් භාවිතා කිරීමට ඉගෙන ගන්නා අතර, ජාවා සහ සී # ක්රමලේඛකයින් එය තේරුම් නොගෙන දර්ශක භාවිතා කිරීමෙන් ආරම්භ වේ ! එය වචනාර්ථයෙන් වැරදි පාදයෙන් ඉවත් වීමයි. සින්ටැක්ස් එක දෙයක් නිසා, භාෂාව ඉගෙනීම තවත් දෙයක් නිසා ඔබ දන්නා සියල්ල අතහැර දැමිය යුතුයි.
1. (N) RVO - අකා, (නම් කරන ලද) ප්රතිලාභ අගය ප්රශස්තකරණය
බොහෝ සම්පාදකයින් විසින් සිදුකරන එක් ප්රශස්තිකරණයක් වන්නේ එලිසන් සහ ප්රතිලාභ අගය ප්රශස්තිකරණය යනුවෙනි . බොහෝ මූලද්රව්ය අඩංගු දෛශිකයක් වැනි ඉතා විශාල වස්තූන් සඳහා ප්රයෝජනවත් වන අනවශ්ය පිටපත් මේ දේවල් මග හැරිය හැක. සාමාන්යයෙන් පොදු සිරිත වන්නේ අයිතිය පැවරීම සඳහා දර්ශක භාවිතා කිරීමයි විශාල වස්තූන් එහා මෙහා ගෙනයාම වෙනුවට පිටපත් කිරීම වෙනුවට කිරීමයි. මෙය චලනය අර්ථ නිරූපණයන් සහ ස්මාර්ට් පොයින්ටර්ස් ආරම්භ කිරීමට හේතු වී තිබේ .
ඔබ දර්ශක භාවිතා කරන්නේ නම්, (N) RVO සිදු නොවේ . ඔබ ප්රශස්තිකරණය ගැන කනස්සල්ලට පත්වුවහොත්, දර්ශකයන් ආපසු යැවීමට හෝ පසුකර යාමට වඩා (N) RVO හි වාසිය ලබා ගැනීම වඩා වාසිදායක සහ අඩු දෝෂ සහිත වේ. ශ්රිතයක ඇමතුම්කරු වගකිව යුතු නම් දෝෂ කාන්දුවීම් සිදුවිය හැකියdelete
ගතිකව වෙන් කරන ලද වස්තුවක් . උණුසුම් අර්තාපල් මෙන් දර්ශකයන් වටා ගමන් කරන්නේ නම් වස්තුවක හිමිකාරිත්වය සොයා ගැනීම දුෂ්කර විය හැකිය. එය සරල හා වඩා හොඳ බැවින් ස්ටක් විචල්යයන් භාවිතා කරන්න.