Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana Memaksa Permulaan Ahli Statik dalam C Tanpa Rujukan Eksplisit?

Bagaimana Memaksa Permulaan Ahli Statik dalam C Tanpa Rujukan Eksplisit?

DDD
DDDasal
2024-10-31 05:38:01296semak imbas

 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>

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>

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>

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>

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!

Kenyataan:
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