Sebuah enum X : int
(C #) atau enum class X : int
(C ++ 11) adalah jenis yang memiliki medan batin tersembunyi int
yang dapat menahan nilai apapun. Selain itu, sejumlah konstanta yang X
telah ditentukan didefinisikan pada enum. Dimungkinkan untuk melemparkan enum ke nilai integernya dan sebaliknya. Ini semua benar dalam C # dan C ++ 11.
Dalam C # enums tidak hanya digunakan untuk menyimpan nilai-nilai individual, tetapi juga untuk menahan kombinasi flag bitwise, sesuai rekomendasi Microsoft . Enum semacam itu (biasanya, tetapi tidak harus) didekorasi dengan [Flags]
atribut. Untuk membuat kehidupan pengembang lebih mudah, operator bitwise (OR, AND, dll ...) kelebihan beban sehingga Anda dapat dengan mudah melakukan sesuatu seperti ini (C #):
void M(NumericType flags);
M(NumericType.Sign | NumericType.ZeroPadding);
Saya seorang pengembang C # yang berpengalaman, tetapi telah memprogram C ++ hanya untuk beberapa hari sekarang, dan saya tidak dikenal dengan konvensi C ++. Saya bermaksud menggunakan enum C ++ 11 dengan cara yang sama persis seperti yang biasa saya lakukan di C #. Dalam C ++ 11 operator bitwise pada scoped enums tidak kelebihan beban, jadi saya ingin membebani mereka .
Ini mengundang debat, dan pendapat tampaknya bervariasi di antara tiga opsi:
Variabel tipe enum digunakan untuk menahan bidang bit, mirip dengan C #:
void M(NumericType flags); // With operator overloading: M(NumericType::Sign | NumericType::ZeroPadding); // Without operator overloading: M(static_cast<NumericType>(static_cast<int>(NumericType::Sign) | static_cast<int>(NumericType::ZeroPadding)));
Tapi ini akan melawan filosofi enum yang sangat diketik dari enum C ++ 11.
Gunakan bilangan bulat polos jika Anda ingin menyimpan kombinasi bit enum:
void M(int flags); M(static_cast<int>(NumericType::Sign) | static_cast<int>(NumericType::ZeroPadding));
Tapi ini akan mengurangi segalanya menjadi
int
, meninggalkan Anda tanpa petunjuk tentang jenis apa yang harus Anda masukkan ke dalam metode.Tulis kelas terpisah yang akan membebani operator dan menahan bendera bitwise di bidang bilangan bulat tersembunyi:
class NumericTypeFlags { unsigned flags_; public: NumericTypeFlags () : flags_(0) {} NumericTypeFlags (NumericType t) : flags_(static_cast<unsigned>(t)) {} //...define BITWISE test/set operations }; void M(NumericTypeFlags flags); M(NumericType::Sign | NumericType::ZeroPadding);
( kode lengkap oleh pengguna315052 )
Tetapi kemudian Anda tidak memiliki IntelliSense atau dukungan apa pun untuk mengisyaratkan Anda pada nilai-nilai yang mungkin.
Saya tahu ini adalah pertanyaan subyektif , tetapi: Pendekatan apa yang harus saya gunakan? Pendekatan apa, jika ada, yang paling dikenal di C ++? Pendekatan apa yang Anda gunakan ketika berhadapan dengan bidang bit dan mengapa ?
Tentu saja karena ketiga pendekatan ini berhasil, saya mencari alasan faktual dan teknis, konvensi yang diterima secara umum, dan bukan hanya preferensi pribadi.
Sebagai contoh, karena latar belakang C # saya cenderung pergi dengan pendekatan 1 di C ++. Ini memiliki manfaat tambahan bahwa lingkungan pengembangan saya dapat memberi saya petunjuk tentang nilai-nilai yang mungkin, dan dengan operator enum yang berlebihan ini mudah untuk ditulis dan dipahami, dan cukup bersih. Dan metode tanda tangan menunjukkan dengan jelas nilai seperti apa yang diharapkannya. Tetapi kebanyakan orang di sini tidak setuju dengan saya, mungkin karena alasan yang baik.
enum E { A = 1, B = 2, C = 4, };
, kisarannya adalah 0..7
(3 bit). Dengan demikian, standar C ++ secara eksplisit menjamin bahwa # 1 akan selalu menjadi opsi yang layak. [Secara khusus, enum class
default ke enum class : int
kecuali ditentukan lain, dan dengan demikian selalu memiliki tipe yang mendasari tetap.])