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

Converting Constructor ใน C++: Constructor ที่รับ Argument เดียว

Converting Constructor (Conversion Constructor) คือ Constructor ที่รับ Argument เพียงหนึ่งตัว** (หรือหลายตัวแต่มี Default Arguments จนเหลือ 1 Required Argument) ทำให้เกิด Implicit Conversion จาก Type ของ Argument ไปเป็น Class Type ได้โดยอัตโนมัติ

Syntax


class MyClass {
public:
    MyClass(int value); // Converting Constructor from int
    // หรือ
    MyClass(double value = 0.0); // Converting Constructor from double
};

ตัวอย่าง: Implicit Conversion

#include <iostream>

class MyClass {
    int value_;
public:
    MyClass(int v) : value_(v) { 
        std::cout << "Converting Constructor called: " << v << '\n';
    }
    
    void display() const { 
        std::cout << "Value: " << value_ << '\n'; 
    }
};

int main() {
    MyClass obj(10);      // Direct Initialization
    obj.display();        // Value: 10
    
    obj = 50;             // Implicit Conversion: int -> MyClass
                          // 1. สร้าง Temporary MyClass(50) ด้วย Converting Constructor
                          // 2. Move Assign (หรือ Copy Assign) ให้ obj
    obj.display();        // Value: 50
    
    // การใช้งานอื่นๆ
    func(100);            // Implicit Conversion ใน Argument
    MyClass obj2 = 200;   // Copy Initialization (Implicit Conversion)
}

ผลลัพธ์


Converting Constructor called: 10
Value: 10
Converting Constructor called: 50
Value: 50

ป้องกัน Implicit Conversion: explicit (C++11)


class SafeClass {
public:
    explicit SafeClass(int v) : value(v) {} // explicit
private:
    int value;
};

void func(SafeClass s) {}

int main() {
    SafeClass s1(10);     // OK: Direct Initialization
    // SafeClass s2 = 20;  // Error: Implicit Conversion Blocked
    // func(30);           // Error: Implicit Conversion Blocked
    func(SafeClass(30));  // OK: Explicit Construction
}

Best Practice: explicit โดย Default

  • Single-Argument Constructors ควรเป็น explicit เสมอ (ป้องกัน Surprising Conversions)
  • ยกเว้น: Wrapper Types ที่ออกแบบมาเพื่อ Transparent Interop (เช่น std::string จาก const char*)
  • C++20: explicit(bool) Conditional Explicit

Conversion Operator (User-Defined Conversion)

กลับกัน: Class -> Other Type


class Integer {
    int value_;
public:
    Integer(int v) : value_(v) {}
    
    // Converting Constructor (int -> Integer) - implicit
    // Conversion Operator (Integer -> int) - implicit
    operator int() const { return value_; } 
};

int main() {
    Integer i(42);
    int x = i; // Implicit: Integer -> int via operator int()
    std::cout << x; // 42
}

สรุป

Converting Constructor (Single-Arg Constructor) เปิดใช้งาน Implicit Conversion ใช้ explicit ป้องกันได้ (Best Practice) Conversion Operator ทำทางกลับ (Class -> Type) ทั้งคู่ต้องใช้ระมัดระวังเพื่อหลีกเลี่ยง Unexpected Behavior