تا اینجا بیشتر با اعداد و رشتهها سروکار داشتهایم. برای مدلسازی دنیای واقعی، ممکن است بخواهیم تعداد محدودی مقدار داشته باشیم که یک متغیر میتواند بپذیرد. ممکن است بخواهید یک نوع اختصاصی با چند مقدار متمایز و اسمهای متمایز داشته باشید. برای مثال، در یک کارخانهی اسکیتبرد ممکن است بخواهید جنس تخته فقط یکی از گزینههای افرا، بامبو یا پلاستیک باشد.
میتوانستید برای کدگذاری آن مقادیر از اعداد صحیح استفاده کنید، اما آنوقت باید کد اضافهای مینوشتید تا بررسی کنید آیا مقدار نامعتبری از سمت سیستم برای جنس میآید یا نه.
ردیابی معنای آن اعداد جادویی در سراسر کد دشوار است و بهراحتی با هم اشتباه گرفته میشوند.
میتوان از enumerations استفاده کرد تا کد گویاتری بنویسیم و اشتباههای مقایسهای ناخواسته را محدود کنیم.
اصطلاح دقیق این نوع شمارشی، scoped enumeration است.
قطعهکد زیر نشان میدهد چطور یک enumeration با اسم DeckMaterial بنویسیم.
به کلیدواژهی enum class و ; در پایان تعریف توجه کنید:
enum class DeckMaterial {
maple,
bamboo,
plastic
};
حالا به یک تابع قیمتگذاری در فروشگاه اسکیت نگاه کنید و به عملگر تفکیک حوزه (::) توجه کنید که یک enumerator را از enumeration مشخص میکند:
double deck_price(double base_price, DeckMaterial material) {
if(material == DeckMaterial::plastic) {
return base_price * 0.9;
}
return base_price * 1.3;
}
فرض کنید یک enumeration دوم برای جنس چرخ دارید:
enum class WheelMaterial {
steel,
clay,
plastic
};
با اینکه چرخها و تخته هر دو میتوانند از پلاستیک ساخته شوند، این دو را نمیتوان با هم اشتباه گرفت.
آنها دو نوع متفاوتاند: پلاستیک DeckMaterial و پلاستیک WheelMaterial.
هر enumeration، enumerators خودش را در حوزهی خودش دارد، یعنی در namespace خودش.
به همین دلیل به آنها scoped enumerations میگویند.
ممکن است فکر کنید وقتی اسمش scoped است، حتماً unscoped هم وجود دارد، و حق با شماست.
Unscoped enumerations کمطرفدارتر میشوند، چون همهشان یک فضای نام سراسری مشترک دارند.
بهخاطر همین اشتراک، نمیتوانستید دو unscoped enumerations داشته باشید که enumerators یکسانی مثل پلاستیک داشته باشند.
همچنین، unscoped enumerations بهطور ضمنی به اعداد صحیح تبدیل میشوند.
به مثال زیر نگاه کنید تا نتیجهی غافلگیرکنندهای ببینید:
enum CitrusFruits {
lemons, // 0
oranges, //1
};
enum IceCream {
walnut, // 0
apples, // 1
};
bool comparison{apples == oranges};
// => true
// Example from above:
bool comparison{DeckMaterial::plastic == WheelMaterial::plastic};
// => Does not compile!
اگر میخواهید scoped enumerations را به اعداد صحیح تبدیل کنید، میتوانید از static_cast<int> استفاده کنید.