C ++ di mana menginisialisasi const statis

129

saya ada kelas

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

Di mana tempat terbaik untuk menginisialisasi string sdalam file sumber?

Thomas
sumber

Jawaban:

178

Di mana saja dalam satu unit kompilasi (biasanya file .cpp) akan melakukan:

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;

(*) Menurut standar Anda harus mendefinisikan di iluar definisi kelas (seperti jadalah) jika digunakan dalam kode selain dari ekspresi konstan yang tidak terpisahkan. Lihat komentar David di bawah untuk detailnya.

squelart
sumber
27
Saya telah memutakhirkan, tetapi setelah meninjau standar ada kesalahan dalam kode Anda: iharus didefinisikan dalam cpp. §9.4.2 / 4 Jika anggota data statis adalah tipe const integral atau enumeration, pernyataannya dalam definisi kelas dapat menentukan penginisialisasi konstan yang harus berupa ekspresi konstanta integral (5.19). Dalam hal itu, anggota dapat muncul dalam ekspresi konstan integral. Anggota masih harus didefinisikan dalam lingkup ruang nama jika digunakan dalam program dan definisi ruang lingkup namespace tidak boleh berisi penginisialisasi.
David Rodríguez - dribeas
3
Berdasarkan kutipan Anda dari standar, tampaknya iharus didefinisikan hanya jika digunakan di tempat lain selain dalam ekspresi konstan yang tidak terpisahkan, kan? Dalam hal ini Anda tidak dapat mengatakan bahwa ada kesalahan karena tidak ada konteks yang cukup untuk memastikan - atau dengan tegas mengatakan contoh di atas adalah benar jika tidak ada kode lain. Sekarang saya sangat menghargai komentar Anda (+1), saya masih belajar sendiri! Jadi saya akan mencoba menjelaskan poin itu dalam jawaban, tolong beri tahu saya jika itu lebih baik ...
squelart
@squelart Maaf jika saya terdengar bodoh tetapi contoh pernyataan selain ekspresi konstanta integral akan?
Saksham
3
@ Saksham Misalnya memanggil fungsi, misalnya: int f() { return 42; } class foo { static const int i = f(); /* Error! */ }Perhatikan bahwa C ++ 11 memungkinkan memanggil fungsi 'constexpr':constexpr int f() { return 42; } class foo { static const int i = f(); /* Ok */ }
squelart
@squelart Saya membaca teks sehingga definisi harus diberikan jika anggota digunakan sama sekali - kata-kata dalam standar tidak membatasi persyaratan untuk ekspresi konstan integral.
VladLosev
12

Anggota statis perlu diinisialisasi dalam unit terjemahan .cpp pada ruang lingkup file atau dalam namespace yang sesuai:

const string foo::s( "my foo");
Michael Burr
sumber
11

Di unit terjemahan dalam namespace yang sama, biasanya di atas:

// 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;
}
GManNickG
sumber
8

Sejak C ++ 17 specifier sebaris juga berlaku untuk variabel. Anda sekarang dapat mendefinisikan variabel anggota statis dalam definisi kelas:

#include <string>

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

Hanya nilai integral (mis., static const int ARRAYSIZE) Diinisialisasi dalam file header karena mereka biasanya digunakan dalam header kelas untuk mendefinisikan sesuatu seperti ukuran array. Nilai-nilai non-integral diinisialisasi dalam file implementasi.

Behnam Dezfouli
sumber