정적 const를 초기화하는 C ++ 위치


129

수업이 있습니다

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

s소스 파일에서 문자열을 초기화하는 가장 좋은 장소는 어디 입니까?

답변:


178

하나의 컴파일 단위 (보통 .cpp 파일)에있는 모든 곳에서

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;

(*) 표준에 따르면, 정수 상수 표현식 이외의 코드에서 사용되는 경우 i클래스 정의 외부에서 정의해야합니다 j. 자세한 내용은 아래 David의 의견을 참조하십시오.


27
나는 공감했지만 표준을 검토 한 후 코드에 오류가 있습니다 . cpp에 정의 되어 i있어야합니다 . §9.4.2 / 4 정적 데이터 멤버가 const 정수 또는 const 열거 형인 경우 클래스 정의에서 선언하면 상수-초기화 기를 지정할 수 있으며 이는 정수 상수 표현식 (5.19)이어야합니다. 이 경우 멤버는 정수 상수 표현식으로 나타날 수 있습니다. 멤버가 프로그램에서 사용되는 경우 네임 스페이스 범위에서 멤버를 정의해야하며 네임 스페이스 범위 정의에 이니셜 라이저가 포함되어서는 안됩니다.
David Rodríguez-dribeas

3
표준에서 인용 한 내용을 토대로 적분 상수 표현식이 아닌 다른 곳에서 사용한 경우 에만i 정의 해야하는 것 같습니다 . 이 경우 컨텍스트가 충분하지 않아서 오류가 있다고 말할 수 없습니다. 또는 다른 코드가 없으면 위의 예제를 엄격하게 말하면 정확합니다. 이제 귀하의 의견에 감사 드리며 (+1), 나는 여전히 스스로 배우고 있습니다! 그래서 대답에서 그 요점을 분명히하려고 노력할 것입니다, 그것이 더 나은지 알려주세요 ...
squelart

@squelart 바보처럼 들리면 미안하지만 정수 상수 표현 이외의 문장 예는 무엇입니까?
Saksham

3
@Saksham 예를 들어 함수 호출 예 : int f() { return 42; } class foo { static const int i = f(); /* Error! */ }C ++ 11은 'constexpr'함수 호출을 허용합니다.constexpr int f() { return 42; } class foo { static const int i = f(); /* Ok */ }
squelart

@squelart 나는 멤버가 전혀 사용되는 경우 정의를 제공 해야하는 텍스트를 읽었습니다. 표준의 문구는 그 상수 요구 사항을 상수 상수로 제한하지 않습니다.
VladLosev

12

정적 멤버는 파일 범위 또는 적절한 네임 스페이스에서 .cpp 변환 단위로 초기화해야합니다.

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

11

동일한 네임 스페이스 내에서 일반적으로 맨 위에있는 번역 단위

// 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부터 인라인 지정자는 변수에도 적용됩니다. 이제 클래스 정의에서 정적 멤버 변수를 정의 할 수 있습니다.

#include <string>

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

1

정수 값 (예 :) 만 static const int ARRAYSIZE일반적으로 클래스 크기에서 배열의 크기와 같은 것을 정의하는 데 사용되므로 헤더 파일에서 초기화됩니다. 비 적분 값은 구현 파일에서 초기화됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.