ภาพรวม
การ Initialize ตัวแปรใน C++ หมายถึงการกำหนดค่าเริ่มต้นตอนสร้างตัวแปร มี 2 แบบหลัก:
- Static Initialization: ค่าคงที่ Compile-time (Global, Static, Constexpr)
- Dynamic Initialization: ค่าที่คำนวณได้ Runtime (Local Variables, Constructor Calls)
Syntax พื้นฐาน
Type variable_name = value; // Copy Initialization
Type variable_name(value); // Direct Initialization
Type variable_name{value}; // List Initialization (C++11) - แนะนำ
Type variable_name = {value}; // Copy List Initialization (C++11)
ตัวอย่างโค้ด
#include <iostream>
using namespace std;
int main() {
// Static Initialization (Global/Static/Constexpr)
static int globalCounter = 0; // Zero-initialized แล้ว Assign 0
// Dynamic Initialization (Local Variables)
int a = 20; // Copy Init
int b(30); // Direct Init
int c{40}; // List Init (C++11) - แนะนำ
int d = {50}; // Copy List Init
cout << "Static Initialization (globalCounter): " << globalCounter << "\n";
cout << "Dynamic Initialization:\n";
cout << " a = " << a << " (copy init)\n";
cout << " b = " << b << " (direct init)\n";
cout << " c = " << c << " (list init - C++11)\n";
cout << " d = " << d << " (copy list init)\n";
// Dynamic Input Initialization
int input;
cout << "\nEnter a value for input: ";
cin >> input; // Runtime Initialization
cout << "Input value: " << input << "\n";
return 0;
}
ผลลัพธ์ตัวอย่าง
Static Initialization (globalCounter): 0
Dynamic Initialization:
a = 20 (copy init)
b = 30 (direct init)
c = 40 (list init - C++11)
d = 50 (copy list init)
Enter a value for input: 28
Input value: 28
ประเภทการ Initialize แบบละเอียด
1. Zero Initialization
int a; // Global/Static: 0
static int b; // 0
int* p; // Global/Static: nullptr
// Local (Non-static): Indeterminate (Garbage)!
2. Default Initialization
int a; // Local: Indeterminate
MyClass obj; // Calls Default Constructor
// ถ้าไม่มี User-Defined Constructor: Members Uninitialized!
3. Value Initialization
int a{}; // 0 (C++11)
int b(); // ❌ Most Vexing Parse: Function Declaration!
int c = int(); // 0
MyClass obj{}; // Zero-init then Default Constructor
new int(); // 0 (Heap)
4. List Initialization (C++11) - แนะนำ
int a{10}; // Direct List Init
int b = {20}; // Copy List Init
int c{}; // Value Init (0)
vector v{1,2,3};// Aggregate Init
// Narrowing Conversions: Error/Warning
// int x{3.14}; // Error: Narrowing (double → int)
// int y = {3.14}; // Error: Narrowing
5. Reference Initialization
int a = 10;
int& ref = a; // Lvalue Reference
const int& cref = 20; // Const Lvalue Ref to Temporary
int&& rref = 30; // Rvalue Reference (C++11)
Best Practices (Modern C++)
- ใช้ Uniform Initialization
{}(C++11) - ป้องกัน Narrowing, Most Vexing Parse, ใช้ได้ทุกที่ - Initialize ทุกตัวแปรเสมอ - หลีกเลี่ยง Uninitialized Variables
- ใช้
autoกับ{}-auto x = 42;(int),auto y{42};(int, C++17) - Const by Default:
const int x = 42;หรือconst auto x = 42; - Member Initialization ใน Constructor: ใช้ Member Initializer List
Member Initialization (Constructor)
class Point {
int x_, y_;
public:
// ❌ Assignment in Body (Less Efficient for Non-Primitive)
Point(int x, int y) { x_ = x; y_ = y; }
// ✅ Member Initializer List (Recommended)
Point(int x, int y) : x_(x), y_(y) {}
// ✅ C++11: In-Class Member Initializers
// int x_ = 0; int y_ = 0; // Default Values
};
สรุปการเลือกใช้
| สถานการณ์ | Syntax แนะนำ | เหตุผล |
|---|---|---|
| Local Variable (Known Value) | int x{42}; | Uniform Init, No Narrowing |
| Local Variable (From Expression) | auto x = expr; | Type Deduction, Clear |
| Member Variable (Default) | int x_ = 0; (In-Class) | Visible Default, DRY |
| Member Variable (Constructor) | : x_(param) | Direct Init, No Default+Assign |
| Global/Static | int x = 42; | Constant Expression Preferred |
| Constexpr | constexpr int x = 42; | Compile-time Constant |