IT Share you

C ++에서 정적 const 멤버를 초기화하는 방법은 무엇입니까?

shareyou 2020. 11. 30. 20:17
반응형

C ++에서 정적 const 멤버를 초기화하는 방법은 무엇입니까?


생성자 외부에서 정적 const 값을 초기화 할 수 있습니까? 멤버 선언이있는 곳에서 초기화 할 수 있나요?

class A {
private:
  static const int a = 4;
  /*...*/
};

예, 가능하지만 int 유형에만 해당됩니다. 정적 멤버가 다른 유형이되도록하려면 cpp 파일의 어딘가에 정의해야합니다.

class A{
private:
 static const int a = 4; // valid
 static const std::string t ; // can't be initialized here
 ...
 ...
};


// in a cpp file where the static variable will exist 
const std::string A::t = "this way it works";

또한이 규칙은 C ++ 11에서 제거되었으므로 이제 (기능을 제공하는 컴파일러를 사용하여) 클래스 멤버 선언에서 원하는 것을 직접 초기화 할 수 있습니다.


정적 데이터 멤버 (C ++ 전용)

클래스의 멤버 목록에서 정적 데이터 멤버의 선언은 정의가 아닙니다. 네임 스페이스 범위에서 클래스 선언 외부의 정적 멤버를 정의해야합니다. 예를 들면 :

class X
{
public:
      static int i;
};
int X::i = 0; // definition outside class declaration

정적 데이터 멤버를 정의하면 정적 데이터 멤버 클래스의 개체가 없어도 존재합니다. 위의 예에서는 정적 데이터 멤버 X :: i가 정의 된 경우에도 클래스 X의 개체가 존재하지 않습니다.

네임 스페이스 범위에있는 클래스의 정적 데이터 멤버에는 외부 연결이 있습니다. 정적 데이터 멤버의 이니셜 라이저는 멤버를 선언하는 클래스 범위에 있습니다.

정적 데이터 멤버는 const 또는 volatile로 한정된 void 또는 void를 제외한 모든 유형이 될 수 있습니다. 정적 데이터 멤버를 변경 가능으로 선언 할 수 없습니다.

프로그램에서 정적 멤버의 정의를 하나만 가질 수 있습니다. 명명되지 않은 클래스, 명명되지 않은 클래스에 포함 된 클래스 및 로컬 클래스는 정적 데이터 멤버를 가질 수 없습니다.

정적 데이터 멤버와 해당 이니셜 라이저는 클래스의 다른 정적 개인 및 보호 멤버에 액세스 할 수 있습니다. 다음 예제는 이러한 멤버가 비공개 인 경우에도 다른 정적 멤버를 사용하여 정적 멤버를 초기화하는 방법을 보여줍니다.

class C {
      static int i;
      static int j;
      static int k;
      static int l;
      static int m;
      static int n;
      static int p;
      static int q;
      static int r;
      static int s;
      static int f() { return 0; }
      int a;
public:
      C() { a = 0; }
      };

C c;
int C::i = C::f();    // initialize with static member function
int C::j = C::i;      // initialize with another static data member
int C::k = c.f();     // initialize with member function from an object
int C::l = c.j;       // initialize with data member from an object
int C::s = c.a;       // initialize with nonstatic data member
int C::r = 1;         // initialize with a constant value

class Y : private C {} y;

int C::m = Y::f();
int C::n = Y::r;
int C::p = y.r;       // error
int C::q = y.f();     // error

C :: p 및 C :: q의 초기화는 y가 C에서 개인적으로 파생 된 클래스의 객체이고 해당 멤버가 C의 멤버에 액세스 할 수 없기 때문에 오류를 발생시킵니다.

정적 데이터 멤버가 const 정수 또는 const 열거 형인 경우 정적 데이터 멤버의 선언에 상수 이니셜 라이저를 지정할 수 있습니다. 이 상수 이니셜 라이저는 정수 상수 표현식이어야합니다. 상수 이니셜 라이저는 정의가 아닙니다. 둘러싸는 네임 스페이스에서 정적 멤버를 정의해야합니다. 다음 예제는이를 보여줍니다.

#include <iostream>
using namespace std;

struct X {
  static const int a = 76;
};

const int X::a;

int main() {
  cout << X::a << endl;
}

The tokens = 76 at the end of the declaration of static data member a is a constant initializer.


Just for the sake of completeness, I am adding about the static template member variables.

template<class T> struct X{
   static T x;
};

template<class T> T X<T>::x = T();

int main(){
   X<int> x;
}

You cannot initialize static members within constructors. Integral types you can initialize inline at their declaration. Other static members must be defined (in a .cpp) file:

// .h
class A{
private:
 static const int a = 4;
 static const foo bar;
 ...
 ...
};

// .cpp
const foo A::bar = ...;

참고URL : https://stackoverflow.com/questions/3531060/how-to-initialize-a-static-const-member-in-c

반응형