2014-09-30 26 views
11

Sabit c-dizelerini şu şekilde tanımlıyorum:C++ 'da sabit bir C-string tanımlamak için doğru yolu?

static char const* MY_CONSTANT = "Hello World"; 

Ancak işaretçisiconst değildir. Aşağıdaki gibi yapmak daha uygun olmaz mıydı?

static char const* const MY_CONSTANT = "Hello World"; 

Bunun gibi sabit globals ile 2 gol vardır:

  1. dizesinin değiştirilmesine izin verme Değişkenin başka bir şeye işaret etmesine izin verme

Sabit dizeleri tanımlarken bu 2 hedefe ihtiyaç olduğunu varsaydım.

Başka bir ilginç şey şudur:

int main() 
{ 
    auto MY_CONSTANT = ""; 
    MY_CONSTANT = "Another String"; 
} 

Bu bana auto dizesinin char const* olarak değil char const* const olarak çıkarılmasını söyler.

İki temel soru var:

  1. Sabit c stili dizeleri tanımlamak için en uygun yol hangisidir (Sanırım sabit bir işaretçi-bir şey, daha genel bir soru mu?). Neden birini veya diğerini seçiyorsun?
  2. auto ile olan örneğim ile ilgili olarak, neden char const*'i seçtiğinin anlaşılması mantıklıdır (çünkü sabit olan veri dizisi, işaretçinin kendisi değil). Xzx46 için auto çıkarımı yapabilir miyim veya böyle bir türle sonuçlanacak şekilde kodu değiştirebilir miyim?
+0

Eğer 'const char * const' olmasın? – Adam

+4

@Adam Her iki form da geçerlidir C++. Seninki benimkiyle aynı. –

+1

'auto' algıladığı varsayılan en küçük kısıtlamadır, yani değişkenin yeniden atanamaması sadece sizin seçiminizdir. Yapabilirsin, eğer istersen, ama herkese empoze etmemenin en iyisi. –

cevap

6

Eh o gerçekten o zaman constexpr bunu yapmak için C++ 11 yol olacağını sabit bir eğer:

constexpr char const* MY_CONSTANT = "Hello World"; 

ilk örnek:

static char const* MY_CONSTANT = "Hello World"; 

Sadece diyor Statik depolama süresine sahip bir char const göstericisine sahip olursunuz; bu, eğer bir işlev dışındaysa, onu global yapar.

İşaretçinin de const olmasını istemiş olsaydık, tanıtılan ikinci forma ihtiyacımız var. Her şey, işaretçinin gerçekten yapılıp yapılmayacağına bağlıdır. Çoğu durumda, üst düzey const olmadan kodunuzu görmeniz sebebi, işaretçinin de const olması anlamına gelmediği için bunu eklemeyi unutmalarıdır. Bir const üyesi olmak isteyip eğer statik örneğin bir fark yaratıyor

örneği veya başına sınıfı:

class A 
{ 
     char const* const const_per_instance = "Other Const String"; 
    public: 
     constexpr static char const* const const_per_class = "Hello World" ; 
}; 

o zaman başına sınıfına olmak const gerektiriyorsa Aksi halde, statik'u kullanmamız gerek.

class A 
{ 
     char const* const const_per_instance = "Other Const String"; 
    public: 
     static char const* const const_per_class ; 
}; 

char const* const A::const_per_class = "Hello World" ; 

ama özü sadece sözdizimi farklıdır aynı şekilde yapılır: constexpr kullanmasına izin verilmez ise örnek hafifçe değişir. Gotw #92 olarak ikinci soru için

oto üst düzey const, verilen bir örnek düşer diyor aşağıdaki gibidir:

const int ci = val; 
auto  g = ci; 

ve şöyle der: g

türü int.

Unutmayın, çünkü sadece bir const olmanızın gerekip gerekmediğine dair herhangi bir kodunun const olmasıdır. Bu ayrı bir değişkendir. Eğer biz const olmasını g istedik, biz c durumunda olduğu gibi const auto söylerdi

aşağıdaki gibidir sevk edilirken Yukarıdaki örnek:

int   val = 0; 
//.. 
const auto c = val; 
+1

Üzgünüz constexpr, msvc'de desteklenmiyor 12 :-( –

+0

@ void.pointer gerek yok * constexpr * cevap sadece sözdizimini değiştirmiyor. * Constexpr * içermeyen bir örneği içerecek şekilde cevabı da güncelledim –

0

Bir const değerine işaret eden işaretçinin üzerine yazmanızın gerçekleştiği nadir bir durumdur, bu nedenle çoğu geliştirici ikinci const'ı çıkarır ancak semantically gerçekten bu şekilde doğru olur:

static char const* const MY_CONSTANT = "Hello World"; 

veya

static const char* const MY_CONSTANT = "Hello World"; 

constexpr, bu gibi başka bir constexpr işlevinin parçasıysa gereklidir:

static constexpr const char* const MY_CONSTANT = "Hello World"; 
static constexpr const char* Foo() 
{ 
    // ... 
    return MY_CONSTANT; 
} 
2
constexpr auto& MY_CONSTANT = "Hello World"; 
  • MY_CONSTANT sahiptir tip const char (&)[12]
  • Bozulma yok (dizi bağlı değil)
  • Herşey Sabit - dizinin kendisi ve
  • MY_CONSTANT sahip iç bağlantı nedeniyle constexpr ve başlıkları
  • kullanılabilen referans - dizinin kendisi ve (tanımı gereği), referans
  • şey (derleme zamanında kullanılabilir) constexpr olduğu
+0

VC++ 'statik auto & MY_CONSTANT =" Hello World "ile' 'yerine kullanılabilir – user2665887

+0

' statik', sabitlemeyle ilgisi yoktur.Bu, diğer derleme birimlerinde fonksiyonun görünmediği anlamına gelir. –

0

İşaretçi parçası üzerindeki const'u fark etmek için aferin! Birçok insan bunun farkında değil.

Dize değişmezinin çeviri birimi başına çoğaltılmasını önlemek (veya en iyileştiricinin string havuzu bölümünün daha kolay olmasını sağlamak) için, gerçek verileri bir kaynak dosyaya yerleştirmeyi öneririm. Metni değiştirirseniz, bu da bazı yeniden kaydetme kaydeder.

başlık:

extern const char *const mystring;

kaynağı

extern const char *const mystring = "hello";

Alternatif

başlık:

extern const std::string mystring;

kaynak:

extern std::string mystring = "hello";

İlgili konular