Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

การ Initialize Const Member ใน Constructor: Member Initializer List

ใน C++ const Member Variable ต้องถูก Initialize (กำหนดค่าเริ่มต้น) ครั้งเดียวเท่านั้น และต้องทำใน Member Initializer List** ของ Constructor ไม่สามารถ Assign ได้ภายใน Body ของ Constructor

Syntax


class ClassName {
    const Type memberName;
public:
    ClassName(ParamType param) : memberName(param) { // Initializer List
        // Body: ไม่สามารถ assign memberName ได้แล้ว
    }
};

ตัวอย่างสมบูรณ์

#include <iostream>
#include <string>

class Config {
    const int maxConnections;
    const std::string serverName;
    const double timeout;

public:
    // Initializer List: เรียงตามลำดับ Declaration ใน Class (ไม่ใช่ลำดับใน List)
    Config(int maxConn, std::string name, double t) 
        : maxConnections(maxConn), 
          serverName(std::move(name)), // Move Semantics (C++11)
          timeout(t) 
    {
        // Body: ใช้สำหรับ Logic อื่นๆ เท่านั้น
        std::cout << "Config created for " << serverName << '\n';
    }

    void print() const {
        std::cout << "Max Conn: " << maxConnections 
                  << ", Server: " << serverName 
                  << ", Timeout: " << timeout << '\n';
    }
};

int main() {
    Config cfg(100, "Production-Server", 30.5);
    cfg.print();
    // Output:
    // Config created for Production-Server
    // Max Conn: 100, Server: Production-Server, Timeout: 30.5
}

กรณีที่บังคับต้องใช้ Initializer List

กรณีเหตุผล
const Memberไม่สามารถ Assign ได้หลัง Construction
Reference Memberต้อง Bind ตั้งแต่สร้าง (int& ref)
Base Class Constructor ที่มี Parameterต้องส่ง Argument ให้ Base
Member Class ที่ไม่มี Default Constructorต้องส่ง Argument ให้ Member Constructor

ลำดับการ Initialize

Member ถูก Initialize ตามลำดับที่ประกาศใน Class Definition ไม่ใช่ลำดับใน Initializer List (Compiler จะ Warn หากลำดับไม่ตรง)


class Foo {
    int a;
    int b;
public:
    Foo() : b(10), a(b + 5) { } // Warning: 'a' initialized before 'b'!
    // a ใช้ค่า b ก่อน b ถูก Initialize -> Undefined Behavior
};

C++11 In-Class Member Initialization (Alternative)

สำหรับ Default Values สามารถ Initialize ได้ที่ Declaration:


class Settings {
    const int defaultPort = 8080;        // C++11
    const std::string defaultHost = "localhost"; 
public:
    Settings() = default; // ใช้ Default Values
    Settings(int port) : defaultPort(port) {} // Override ได้ใน Initializer List
};

Best Practices

  • ใช้ Initializer List เสมอ สำหรับ Members ทั้งหมด (Performance: หลีกเลี่ยง Default Construct + Assign)
  • เรียงลำดับใน List ให้ตรงกับ Declaration Order
  • ใช้ std::move สำหรับ Parameter ที่เป็น Rvalue/Expensive-to-copy
  • Mark Constructor explicit หาก Single Parameter (ป้องกัน Implicit Conversion)

สรุป

Member Initializer List เป็นกลไกพื้นฐานของ C++ สำหรับ Initialize Members อย่างถูกต้องและมีประสิทธิภาพ const และ Reference Members บังคับให้ใช้ Initializer List เท่านั้น การเข้าใจลำดับการ Initialize และ In-Class Initialization (C++11) ช่วยเขียน Constructor ที่ปลอดภัยและสะอาด