Bagaimana Memaksa Permulaan Ahli Statik dalam C Tanpa Rujukan Eksplisit?

DDD
Lepaskan: 2024-10-31 05:38:01
asal
295 orang telah melayarinya

 How to Force Initialization of a Static Member in C   Without Explicit Referencing?

Cara Memaksa Permulaan Ahli Statik

Tingkah laku yang sering diabaikan dalam C ialah ahli statik tidak dijamin untuk dimulakan secara automatik. Seseorang mungkin menjangkakan bahawa ahli itu dimulakan dengan instantiasi pertama kelas konkrit. Walau bagaimanapun, seperti yang dicadangkan oleh petikan standard, ini berlaku hanya apabila ahli statik digunakan secara aktif:

"* khususnya, permulaan (dan sebarang kesan sampingan yang berkaitan) bagi ahli data statik tidak berlaku melainkan ahli data statik itu sendiri digunakan dalam cara yang memerlukan takrifan ahli data statik untuk wujud."

Masalahnya

Pertimbangkan kod berikut:

<code class="cpp">template <class D>
char register_() {
  return D::get_dummy(); // static function
}

template <class D>
struct Foo {
  static char const dummy;
};

template <class D>
char const Foo<D>::dummy = register_<D>(); // static member initialized with `register_<D>()`

struct Bar : Foo<Bar> {
  static char const get_dummy() { return 42; }
};</code>
Salin selepas log masuk

Secara intuitif, seseorang mungkin menjangkakan dummy akan dimulakan selepas instantiasi Bar. Walau bagaimanapun, ini tidak berlaku.

Persoalannya

Bagaimanakah seseorang boleh memaksa pemulaan dummy tanpa memerlukan instance Bar atau Foo? Selain itu, penyelesaian itu tidak sepatutnya memerlukan rujukan eksplisit ahli oleh pengguna Foo.

Penyelesaian Berpotensi

Penyelesaian 1 (Kesan Minimum pada Kelas Terbitan)

Pengubahsuaian berikut kepada kaedah get_dummy() Bar akan memaksa pemulaan dummy:

<code class="cpp">static char const get_dummy() { (void)dummy; return 42; }</code>
Salin selepas log masuk

Penyelesaian 2 (Tiada Pengubahsuaian kepada Kelas Terbitan)

Penyelesaian ini menggunakan metaprogramming templat:

<code class="cpp">template<typename T, T> struct value { };

template<typename T>
struct HasStatics {
  static int a; // we force this to be initialized
  typedef value<int&, a> value_user;
};

template<typename T>
int HasStatics<T>::a = /* whatever side-effect you want */ 0;</code>
Salin selepas log masuk

Atau, ia boleh dilakukan tanpa memperkenalkan mana-mana ahli tambahan:

<code class="cpp">template<typename T, T> struct var { enum { value }; };

template<typename T>
struct HasStatics {
  static int a; // we force this to be initialized
  static int b; // and this
  char user :var<int&, a>::value,
       :var<int&, b>::value;
};

template<typename T>
int HasStatics<T>::a = /* whatever side-effect you want */ 0;

template<typename T>
int HasStatics<T>::b = /* whatever side-effect you want */ 0;</code>
Salin selepas log masuk

Atas ialah kandungan terperinci Bagaimana Memaksa Permulaan Ahli Statik dalam C Tanpa Rujukan Eksplisit?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!