C ++ statik sabitin nerede başlatılacağı


131

Sınıfım var

class foo {
public:
   foo();
   foo( int );
private:
   static const string s;
};

Dizeyi skaynak dosyada başlatmak için en iyi yer neresidir ?

Yanıtlar:


179

Bir derleme biriminin herhangi bir yerinde (genellikle bir .cpp dosyası) şunları yapacaktır:

foo.h

class foo {
    static const string s; // Can never be initialized here.
    static const char* cs; // Same with C strings.

    static const int i = 3; // Integral types can be initialized here (*)...
    static const int j; //     ... OR in cpp.
};

foo.cpp

#include "foo.h"
const string foo::s = "foo string";
const char* foo::cs = "foo C string";
// No definition for i. (*)
const int foo::j = 4;

(*) Standartlara göre , kodda sadece integral sabit ifadeler dışında kullanılıyorsa i, sınıf tanımının dışında (olduğu gibi j) tanımlamalısınız . Ayrıntılar için aşağıdaki David'in yorumuna bakın.


27
Ben upvoted, ancak standart inceledikten sonra kodunda bir hata vardır: iedilmelidir tanımlanan cpp'de içinde. §9.4.2 / 4 Bir statik veri üyesi, const integral veya sabit numaralandırma
David Rodríguez - dribeas

3
Standartlardan yaptığınız alıntıya dayanarak, yalnızca sabit ifadelerden başka bir yerde kullanılmışsa itanımlanması gerekecek gibi görünüyor , değil mi? Bu durumda, emin olmak için yeterli bağlam olmadığı için bir hata olduğunu söyleyemezsiniz - ya da katı bir şekilde konuşmak gerekirse, yukarıdaki örnek başka bir kod yoksa doğrudur. Şimdi yorumunuzu takdir ediyorum (+1), hala bir şeyler öğreniyorum! Bu yüzden cevaptaki bu noktayı açıklığa kavuşturmaya çalışacağım, lütfen daha iyi olup olmadığını bana bildirin ...
squelart

@squelart Aptal gibi geliyorsam özür dilerim ama integral sabit ifadeden başka bir ifade örneği olabilir mi?
Saksham

3
@Saksham Örneğin bir işlevi çağırmak için, örneğin: int f() { return 42; } class foo { static const int i = f(); /* Error! */ }C ++ 11'in 'constexpr' işlevlerinin çağrılmasına izin verdiğini unutmayın:constexpr int f() { return 42; } class foo { static const int i = f(); /* Ok */ }
squelart

@squelart Metni öyle okudum ki, üye kullanılıyorsa tanımın sağlanması gerekir - standarttaki ifade bu gereksinimi integral sabit ifadelerle sınırlamaz.
VladLosev

12

Statik üyelerin dosya kapsamında veya uygun ad alanında bir .cpp çeviri biriminde başlatılması gerekir:

const string foo::s( "my foo");

11

Aynı ad alanı içindeki bir çeviri biriminde, genellikle en üstte:

// foo.h
struct foo
{
    static const std::string s;
};

// foo.cpp
const std::string foo::s = "thingadongdong"; // this is where it lives

// bar.h
namespace baz
{
    struct bar
    {
        static const float f;
    };
}

// bar.cpp
namespace baz
{
    const float bar::f = 3.1415926535;
}

8

C ++ 17'den beri satır içi belirtici değişkenler için de geçerlidir. Artık sınıf tanımında statik üye değişkenleri tanımlayabilirsiniz:

#include <string>

class foo {
public:
   foo();
   foo( int );
private:
   inline static const std::string s { "foo" };
};

1

Yalnızca integral değerler (örneğin static const int ARRAYSIZE) başlık dosyasında başlatılır çünkü bunlar genellikle bir dizinin boyutu gibi bir şeyi tanımlamak için sınıf başlığında kullanılır. İntegral olmayan değerler uygulama dosyasında başlatılır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.