C++

2015-04-22 12 views
8

'daki bayraklar için imzalı vs imzasız değişkenlerin kullanımı Herhangi bir "iyi uygulama" veya imzalı değişkenler kullanılarak imzasız değişkenler vs imzasız değişkenlere karşı var mı? Şahsen ben imzasız değişken kullanırdım, ama bazı kodlarda bayraklar için kullanılan imzalı değişkeni bile görebilirim. Özellikle önemli olduğu kütüphane arayüzünde demek istiyorum.C++

UDPATE implementation dependent olduğu için "kullan Enum" cevabını kabul edemiyorum ve bu kitaplık arabiriminde kullanılamaz.

+0

bayrakları o – Nim

+0

Eğer biraz bayrakların setleri için demek istiyorsun .. Bir enum olması gerektiğini bana ima? Ya da sadece bir bayrak mı? İkinci durumda bir bool kullanacağım. –

+3

@Nim - benim için bayrak bir numara değil - çünkü bayraklar, '|', '&' ve '~' gibi bitly operatörler ile kullanılabilir. – tmp

cevap

0

O bayrakları hep negatif tam sayılardır olduğu bilinmektedir, ama neden int/unsigned int/short/unsigned short bir bayrak için kullanırsınız? #define veya daha da iyisi, enum türünü kullanın.

enum flags 
{ 
    FLAG0 = 0, 
    FLAG1 = 1, 
    FLAG2 = 2, 
    ... 
    FLAGN = n 
}; 
+4

Hayır, '# define' kullanmayın. – user2079303

+3

Lütfen başka bir zaman user2079303 yorumunu okuyun, aslında bunu kalmak için gereken süreyi okuyun. Ve yaygın olarak uygulayın. –

+0

'# define', küçük bayraklarınız varsa (ör. 2 veya 3) ve" enum "bu durumda açık bir kapıyı kırmak gibidir. Daha büyük projelerde her zaman enum kullanmayı öneririm. –

3

Bence imzasız bir tür bayrak kümesinin daha iyi bir temsilidir. Bayraklarınızı temsil etmek için belirli miktarda eşdeğer bit gerektiğinden. İmzalı bir tipte ilk bit, özel bir çeşittir.

Muhtemelen std::bitset da gereksinimlerinizi karşılayabilir. Ve size temel mantıksal işleçler ve dönüşüm yöntemleri ile hizmet verecek. Eğer Bayraklar için enum kullanmaya karar verirseniz

#include <iostream> 
#include <bitset> 
using namespace std; 

int main() { 
    std::bitset<4> flags; 
    flags.set(1); 
    flags.set(3); 
    std::cout << flags.to_string() << std::endl; 
    std::cout << flags.to_ulong() << std::endl; 
    return 0; 
} 

DEMO

+2

Ve bağlantıyı takip etmek için çok tembel olanlar için: '&', '|', '^' ve hatta '[]' için aşırı yüklenmeler var. – TobiMcNamobi

0

, burada enum türü için bit operatörleri için kod oluşturur yararlı bir makrosudur.

#define GENERATE_ENUM_FLAG_OPERATORS(enumType) \ 
    inline enumType operator| (enumType lhs, enumType rhs) \ 
    { \ 
     return static_cast<enumType>(static_cast<int>(lhs) | static_cast<int>(rhs)); \ 
    } \ 
    inline enumType& operator|= (enumType& lhs, const enumType& rhs) \ 
    { \ 
     lhs = static_cast<enumType>(static_cast<int>(lhs) | static_cast<int>(rhs)); \ 
     return lhs; \ 
    } \ 
    inline enumType operator& (enumType lhs, enumType rhs) \ 
    { \ 
     return static_cast<enumType>(static_cast<int>(lhs) & static_cast<int>(rhs)); \ 
    } \ 
    inline enumType& operator&= (enumType& lhs, const enumType& rhs) \ 
    { \ 
     lhs = static_cast<enumType>(static_cast<int>(lhs) & static_cast<int>(rhs)); \ 
     return lhs; \ 
    } \ 
    inline enumType operator~ (const enumType& rhs) \ 
    { \ 
     return static_cast<enumType>(~static_cast<int>(rhs)); \ 
    } 

Kullanımı:

enum Test 
{ 
    TEST_1 = 0x1, 
    TEST_2 = 0x2, 
    TEST_3 = 0x4, 
}; 
GENERATE_ENUM_FLAG_OPERATORS(Test); 

Test one = TEST_1; 
Test two = TEST_2; 

Test three = one | two; 
+0

int yerine std :: underlying_type :: type' kullanmayı tercih ederim. – lisyarus

+0

erm, 'auto three = Test (TEST_1 | TEST_2)' ayrıca varsayılan işleçlerle de iyi çalışır ... – Nim

+0

C++ 03 derleyici ile çalışıyorum, bu yüzden kodum C++ 11 sözdizimini içermiyor :) – rozina