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