C++ Programming မှာ အဖြစ်များတဲ့ အမှားတွေနဲ့ ဘယ်လိုပြင်ရမလဲ
C++ ပရိုဂရမ်းမင်းသည် အစွမ်းထက်ဆုံးနှင့် ပြောင်းလွယ်ပြင်လွယ်အရှိဆုံး ပရိုဂရမ်းမင်းဘာသာစကားများထဲမှ တစ်ခုဖြစ်သည်။ လုပ်ထုံးလုပ်နည်းဆိုင်ရာ၊ အရာဝတ္ထု-ဦးတည်ချက်ဆိုင်ရာ နှင့် အထွေထွေပရိုဂရမ်းမင်းကို ပံ့ပိုးပေးနိုင်သည့် ၎င်း၏စွမ်းရည်ဖြင့် C++ ကို လည်ပတ်မှုစနစ်များမှ မြင့်မားသောစွမ်းဆောင်ရည်ရှိသော ဂိမ်းအက်ပလီကေးရှင်းများအထိ အပလီကေးရှင်းအမျိုးမျိုးတွင် တွင်ကျယ်စွာအသုံးပြုကြသည်။ သို့သော် မည်သည့်ပရိုဂရမ်းမင်းဘာသာစကားကဲ့သို့ပင် C++ တွင် ပရိုဂရမ်းမင်းအသစ်များနှင့် အတွေ့အကြုံရှိသူများ ကြုံတွေ့ရလေ့ရှိသော အဖြစ်များသော အမှားများစွာလည်း ရှိပါသည်။ ဤဆောင်းပါးသည် C++ ပရိုဂရမ်းမင်းတွင် အဖြစ်များသော အမှားအချို့ကို ဆွေးနွေးပြီး ၎င်းတို့ကို မည်သို့ပြင်ဆင်ရမည်ကို လမ်းညွှန်ပေးပါမည်။
၁။ အစပြုမထားသော ညွှန်ပြချက်များကို အသုံးပြုခြင်း
အမှား:
initialized မလုပ်ရသေးတဲ့ pointer တစ်ခုဟာ မသိတဲ့ memory location ကို ညွှန်ပြနိုင်ပြီး မမျှော်လင့်ထားတဲ့ အပြုအမူ ဒါမှမဟုတ် program crash ဖြစ်စေနိုင်ပါတယ်။ ဒီ error ရဲ့ ဥပမာတစ်ခုကတော့ အောက်ပါအတိုင်းပါ။
“`cpp
int ptr; // ptr ကို initialize မလုပ်ရသေးပါ
ptr = 10; // အမှား- pointer ကို initialize မလုပ်ရသေးပါ
``
ဘယ်လိုပြင်ရမလဲ-
အသုံးမပြုမီ pointer ကို initialize လုပ်ပါ။ `nullptr` ဖြင့် သို့မဟုတ် တရားဝင် memory address ဖြင့် initialize လုပ်နိုင်သည်။
“`cpp
int ptr = nullptr; // nullptr ဖြင့် initialize လုပ်ပါ
တန်ဖိုး = ၁၀;
ptr = &တန်ဖိုး;
ptr = 20; // ယခု လုံခြုံပါပြီ
``
၂။ မှတ်ဉာဏ်စီမံခန့်ခွဲမှုတွင် အမှားများ (မှတ်ဉာဏ်ယိုစိမ့်ခြင်း)
အမှား:
ခွဲဝေပေးထားသော မှတ်ဉာဏ်ကို ပြန်လည်ထုတ်လွှတ်ခြင်းမရှိသည့်အခါ မှတ်ဉာဏ်ယိုစိမ့်မှု ဖြစ်ပေါ်ပါသည်။ ၎င်းသည် အပလီကေးရှင်းတစ်ခုအား အချိန်ကြာလာသည်နှင့်အမျှ မှတ်ဉာဏ်ကို ပိုမိုအသုံးပြုစေပြီး နောက်ဆုံးတွင် မှတ်ဉာဏ်ပြတ်လပ်မှုကို ဖြစ်ပေါ်စေနိုင်သည်။
“`cpp
int ptr = int[10] အသစ်;
// ခွဲဝေထားသော မှတ်ဉာဏ်ကို ဖျက်ရန် မေ့သွားခြင်း
``
ဘယ်လိုပြင်ရမလဲ-
ခွဲဝေပေးထားသော မှတ်ဉာဏ်ကို မည်သည့်အရာဖြင့် ခွဲဝေပေးထားသည်ပေါ် မူတည်၍ `delete` သို့မဟုတ် `delete[]` ကို အသုံးပြု၍ အမြဲတမ်း ခွဲဝေပေးထားသော မှတ်ဉာဏ်ကို လွတ်စေရန် သေချာပါစေ။
“`cpp
int ptr = int[10] အသစ်;
// မှတ်ဉာဏ်အသုံးပြုမှု…
delete[] ptr; // လွတ်နေသော မှတ်ဉာဏ်
``
မှတ်ဉာဏ်စီမံခန့်ခွဲမှုကို ပိုမိုလွယ်ကူစေရန်အတွက် smart pointers library (`std::unique_ptr` သို့မဟုတ် `std::shared_ptr` ကဲ့သို့) ကို အသုံးပြုပါ။
“`cpp
ပါဝင်
std::unique_ptr ptr(အသစ် int[10]);
// ptr သည် scope မှထွက်သောအခါ မှတ်ဉာဏ်ကို အလိုအလျောက်ထုတ်လွှတ်လိမ့်မည်။
``
၃။ ရည်ညွှန်းချက်များကို အသုံးပြုရာတွင် အမှားများ
အမှား:
scope ပြင်ပသို့ ရောက်သွားသော reference သို့မဟုတ် pointer ကို local variable သို့ ပြန်ပို့ခြင်းသည် မမျှော်လင့်ထားသော အပြုအမူကို ဖြစ်ပေါ်စေနိုင်သည်။
“`cpp
int& ရည်ညွှန်းချက်ရယူပါ() {
တန်ဖိုး = ၁၀;
return value; // အမှား: local variable တစ်ခုသို့ reference ပြန်ပေးခြင်း
}
``
ဘယ်လိုပြင်ရမလဲ-
local variable များသို့ reference များကို ပြန်ပေးခြင်းကို ရှောင်ကြဉ်ပါ။ ယင်းအစား static variable များကို အသုံးပြုပါ၊ သို့မဟုတ် ပိုကောင်းသည်မှာ တန်ဖိုးများကို ပြန်ပေးခြင်း သို့မဟုတ် object များကို အသုံးပြုရန် စဉ်းစားပါ။
“`cpp
တန်ဖိုးရယူရန် int() {
တန်ဖိုး = ၁၀;
ပြန်ပေးတန်ဖိုး; // ပိုလုံခြုံသည်
}
``
၄။ Compiler အမှားအယွင်း မက်ဆေ့ချ်များနှင့် သတိပေးချက်များကို လျစ်လျူရှုပါ။
အမှား:
ပရိုဂရမ်မာများသည် compiler မှထုတ်ပြန်သော error message များနှင့် warning များကို မကြာခဏ လျစ်လျူရှုလေ့ရှိသော်လည်း၊ ဤ message များသည် ဖြစ်နိုင်ချေရှိသော error များအကြောင်း အရေးကြီးသော အချက်အလက်များကို ပေးစွမ်းသော်လည်း၊
ဘယ်လိုပြင်ရမလဲ-
compiler မှထုတ်ပေးသော error message များနှင့် warning များကို အမြဲစစ်ဆေးပြီး နားလည်ပါ။ code ပိုမိုသန့်ရှင်းစေရန် high level warning များကို enable လုပ်ပါ။
ဥပမာအားဖြင့် GCC တွင်၊ သတိပေးချက်များ ပိုမိုထုတ်ပေးရန် `-Wall` အလံကို အသုံးပြုပါ။
“`ဘေ့စ်
g++ -Wall -o ပရိုဂရမ် main.cpp
``
၅။ အော်ပရေတာ အလွန်အကျွံတင်ဆောင်မှုတွင် အမှားအယွင်း
အမှား:
မှားယွင်းသော operator overloading သည် မမျှော်လင့်ထားသော အပြုအမူ သို့မဟုတ် runtime အမှားများကို ဖြစ်စေနိုင်သည်။
“`cpp
MyClass အတန်း {
အများသူငှာ-
int ဒေတာ;
MyClass အော်ပရေတာ+ (const MyClass& အခြား) {
data + other.data ကို ပြန်ပို့ပါ။ // အမှား- MyClass ကို ပြန်ပေးသင့်သည်။
}
};
``
ဘယ်လိုပြင်ရမလဲ-
overloaded operator သည် သင့်လျော်သော type ကို ပြန်ပေးပြီး class ၏ invariant များကို ထိန်းသိမ်းထားကြောင်း သေချာပါစေ။
“`cpp
MyClass အတန်း {
အများသူငှာ-
int ဒေတာ;
MyClass အော်ပရေတာ+ (const MyClass& အခြား) {
MyClass ရလဒ်;
ရလဒ်.ဒေတာ = ဒေတာ + အခြား.ဒေတာ;
ရလဒ်ကို ပြန်ပို့သည်; // MyClass မှ object တစ်ခုကို ပြန်ပေးသည်
}
};
``
၆။ မက်ခရိုများကို အလွဲသုံးစားလုပ်ခြင်း
အမှား:
မက်ခရိုများကို တစ်ခါတစ်ရံ အလွန်အကျွံ သို့မဟုတ် မှားယွင်းစွာ အသုံးပြုလေ့ရှိသောကြောင့် လည်ပတ်ချိန်တွင် ထောက်လှမ်းရန် ခက်ခဲသော အမှားများ ဖြစ်ပေါ်စေနိုင်သည်။
“`cpp
SQUARE(x) xx ကို အဓိပ္ပာယ်ဖွင့်ဆိုပါ
int ရလဒ် = SQUARE(5 + 1); // အမှား- ရလဒ်က 5 + 1 5 + 1 ဖြစ်တယ်။
``
ဘယ်လိုပြင်ရမလဲ-
ပိုမိုကောင်းမွန်သော type လုံခြုံရေးနှင့် ထိန်းချုပ်မှုအတွက် macro များကို constant expression များ သို့မဟုတ် template များဖြင့် အစားထိုးပါ။
“`cpp
template ကို
T စတုရန်း(T x) {
xx ကို ပြန်ပို့ပါ။
}
int ရလဒ် = square(5 + 1); // အသုံးပြုရန် ဘေးကင်းပါသည်
``
၇။ C-style လုပ်ဆောင်ချက်များကို အလွဲသုံးစားလုပ်ခြင်း
အမှား:
buffer overflow ဖြစ်နိုင်ခြေရှိသော `strcpy` သို့မဟုတ် `sprintf` ကဲ့သို့သော C-style function များကို အသုံးပြုခြင်း။
“`cpp
char src[] = "မင်္ဂလာပါ၊ ကမ္ဘာကြီး!";
char dest[5];
strcpy(dest, src); // အမှား- buffer overflow
``
ဘယ်လိုပြင်ရမလဲ-
`std::string` သို့မဟုတ် `std::vector` ကဲ့သို့သော ပိုမိုလုံခြုံသော C++ function များကို အသုံးပြုပါ။
“`cpp
ပါဝင်
std::string src = “မင်္ဂလာပါ၊ ကမ္ဘာကြီး!”;
std::string dest = src; (ကုဒ်တွေက အင်္ဂလိပ်လိုပဲရေးထားပြီးသားမို့ ဘာသာပြန်စရာမလိုပါဘူး။)
``
၈။ အမှားရှာဖွေခြင်းကို လျစ်လျူရှုခြင်း
အမှား:
I/O လုပ်ဆောင်ချက်များ သို့မဟုတ် ကျရှုံးနိုင်သည့် လုပ်ဆောင်ချက်များတွင် အမှားစစ်ဆေးခြင်းကို လျစ်လျူရှုပါ။
“`cpp
std::ifstream ဖိုင်(“data.txt”);
// အမှား: ဖိုင်ကို အောင်မြင်စွာဖွင့်ထားခြင်း ရှိ၊ မရှိ စစ်ဆေးခြင်း မပြုခဲ့ပါ
``
ဘယ်လိုပြင်ရမလဲ-
လုပ်ငန်းဆောင်ရွက်မှု အောင်မြင်ခြင်း ရှိ၊ မရှိ အမြဲစစ်ဆေးပြီး အမှားအယွင်းများကို သင့်လျော်စွာ ကိုင်တွယ်ဖြေရှင်းပါ။
“`cpp
std::ifstream ဖိုင်(“data.txt”);
(!ဖိုင်) ဖြစ်ပါက {
std::cerr << “ဖိုင်ကိုဖွင့်၍မရပါ” << std::endl;
1 ပြန်လာ;
}
``
၉။ အကောင်းဆုံးမဟုတ်သော ကွင်းဆက်အကောင်အထည်ဖော်မှု
အမှား:
အကောင်းဆုံးမဟုတ်သော loops များကိုအသုံးပြုခြင်းသည် ပရိုဂရမ်စွမ်းဆောင်ရည်ကို ကျဆင်းစေနိုင်သည်။
“`cpp
for (int i = 0; i < vec.size(); i++) {
// vec[i] ဖြင့် လုပ်ဆောင်ခြင်း
// အမှား- size() ကို ထပ်ခါတလဲလဲလုပ်ဆောင်တိုင်း ခေါ်ယူသည်
}
``
ဘယ်လိုပြင်ရမလဲ-
ထပ်ခါတလဲလဲ function call များကို လျှော့ချခြင်းဖြင့် loops များကို အကောင်းဆုံးဖြစ်အောင်ပြုလုပ်ပါ။
“`cpp
for (std::size_t i = 0, n = vec.size(); i < n; i++) {
// vec[i] ဖြင့် လုပ်ဆောင်ခြင်း
}
``
နောက်ထပ် အကောင်းဆုံးဖြစ်အောင် လုပ်ဆောင်ဖို့အတွက် `std::for_each` လိုမျိုး STL algorithms တွေကိုလည်း အသုံးချပါ။
“`cpp
ပါဝင်
std::for_each(vec.begin(), vec.end(), [](int &value) { သည်
// တန်ဖိုးနဲ့ လုပ်ငန်းစဉ်
});
``
၁၀။ Thread ကိုင်တွယ်မှုတွင် အမှားအယွင်း
အမှား:
ချည်မျှင်များကို မှားယွင်းစွာကိုင်တွယ်ခြင်းသည် ပြိုင်ပွဲအခြေအနေများ သို့မဟုတ် အကျပ်အတည်းများကို ဖြစ်ပေါ်စေနိုင်သည်။
“`cpp
void ကို ထည့်သွင်းပါ run() {
// အမှား- လူမျိုးရေးအခြေအနေ ဖြစ်ပေါ်နိုင်သည်
}
std::thread t1(လည်ပတ်သည်);
std::thread t2(လည်ပတ်သည်);
``
ဘယ်လိုပြင်ရမလဲ-
race အခြေအနေများနှင့် deadlock များကို ကာကွယ်ရန် mutexes ကဲ့သို့သော synchronization primitives များကို အသုံးပြုပါ။
“`cpp
ပါဝင်သည် ပါဝင်သည်
std::mutex mtx;
လည်ပတ်မှုပျက်ပြယ်သည် () {
std::lock_guard သော့ခတ်(mtx);
// လူမျိုးရေးအခြေအနေများမှ ဘေးကင်းသော လုပ်ငန်းစဉ်တစ်ခု
}
std::thread t1(လည်ပတ်သည်);
std::thread t2(လည်ပတ်သည်);
t၂။ ချိတ်ဆက်ပါ();
t၂။ ချိတ်ဆက်ပါ();
``
နိဂုံး
C++ သည် အစွမ်းထက်ပြီး ပြောင်းလွယ်ပြင်လွယ်ရှိသော ပရိုဂရမ်းမင်းဘာသာစကားတစ်ခုဖြစ်သော်လည်း အထူးသဖြင့် မှတ်ဉာဏ်နှင့် pointer စီမံခန့်ခွဲမှုနှင့် ဆက်စပ်သော အမှားများလည်း ဖြစ်တတ်ပါသည်။ ဤအမှားများကို နားလည်ခြင်းနှင့် ၎င်းတို့ကို မည်သို့ပြင်ဆင်ရမည်ကို သိရှိခြင်းဖြင့် ပိုမိုယုံကြည်စိတ်ချရပြီး ထိရောက်သော အပလီကေးရှင်းများကို သင် တည်ဆောက် နိုင်ပါသည် ။ compiler မက်ဆေ့ချ်များကို အမြဲအာရုံစိုက်ရန်၊ ဘေးကင်းသောကုဒ်ရေးသားရန် ကူညီပေးသည့် ခေတ်မီကိရိယာများကို အသုံးပြုရန် နှင့် C++ ပရိုဂရမ်းမင်း အကောင်းဆုံးလုပ်ဆောင်မှုများကို နားလည်ပြီး အသုံးချရာတွင် သင့်ကျွမ်းကျင်မှုကို အဆက်မပြတ် မြှင့်တင်ရန် မမေ့ပါနှင့်။