1. 程式人生 > >C++11 強列舉型別的應用

C++11 強列舉型別的應用

一貫的風格,為什麼c++ 11為什麼要引入強列舉型別,主要是為了解決什麼問題?

在此之前我們來看看平時我們的列舉用法:

enum是我們編譯器內建的型別.

首先列舉型別是不安全的,為什麼不安全?

//體重
namespace T {
    enum Type {
        normal,medium,height
    };
}

//商品價格
enum price{
    height = 1 ,normal = 0
};

void isHeight(T::Type t) {
    if(t == height){
        cout << "your weight is height" << endl;
    }
    else
    {
        cout << "youre weight is not height" << endl;
    }
}

我們原本是需要判斷體重是否偏高? 測試時,我們是如此輸入的.

int main(int argc, const char * argv[]) {
    isHeight(T::Type::medium);
    return 0;
}

輸出結果如下 :
consle:
your weight is height。

我們明明輸入的體重是medium,是比較正常的體重,但是判斷出了高體重。

這是因為編譯器在做列舉數值型別比較的時候,會被隱式的轉化為int資料型別,然後再進行int資料型別進行比較.

這是一種非常不安全的比較,一般來說,編譯器會進行提示,但是不會報錯.

為了解決上面的問題,我們引入了強型別的列舉型別,可以幫助我們在編譯截斷進行型別的檢測,幫助我們更好的提升我們程式的健壯性.

下面我們看看我們升級後的寫法:

強型別列舉的定義:

enum class Type {normal,medium,height};

在enum後面加上class關鍵字,就是宣告為強型別列舉型別.

在轉化為強列舉型別後有下面的幾個好處:

1.強列舉型別的作用域不用輸出到父作用域.

怎麼理解?看我們的程式碼:

namespace T {
    enum class Type {
        normal,medium,height
    };
    
    enum Type2 {
        normal,medium,height
    };
}

在使用的時候我們可以使用:
T::normal,T::Type2::normal這樣的寫法.

T::normal大家自己親自去測試,居然是合法的。

WTF???
第一種寫法:T::normald編譯可以通過,那是因為列舉型別可以把自己的作用域擴張到父作用域.

但是如果使用了強列舉型別,那麼作用域就會被鎖定在強列舉的類型範圍內,不會輸出到父作用域,更加嚴謹.

2.在進行型別比較的時候,強列舉型別不會進行隱式的轉換,編譯器會進行型別的檢測.

在這裡插入圖片描述

如果是強型別列舉型別,編譯期間就不會通過,程式更加健壯了。

啊,玩意說了,C++ 11的強列舉型別,還有一個擴充套件的屬性,就是可以指定元素的基本資料型別:

預設我們的enum type {…} 預設都是int型別的,在C++ 11中我們也可以指定為char型別.

機器型號:mac os 64位作業系統

enum class C :: char { C1,C2};
sizeof(C::C1) ; //輸出1

enum class L:: unsigned long {L1,L2};
sizeof(L::L1) ;//輸出8