클래스 정의에서 정적 const 정수 멤버 정의
내 이해는 C ++에서 정수 유형 인 한 클래스 내에서 정적 const 멤버를 정의 할 수있는 것입니다.
그러면 다음 코드에서 링커 오류가 발생하는 이유는 무엇입니까?
#include <algorithm>
#include <iostream>
class test
{
public:
static const int N = 10;
};
int main()
{
std::cout << test::N << "\n";
std::min(9, test::N);
}
내가 얻는 오류는 다음과 가변적입니다.
test.cpp:(.text+0x130): undefined reference to `test::N'
collect2: ld returned 1 exit status
흥미롭게도 std :: min에 대한 호출을 주석 처리하면 코드가 잘되고 연결됩니다 (이전 행 회의 test :: N이 참조 되었음에도 불구하고).
무슨 일이 일어나고 있는지 아십니까?
내 컴파일러는 Linux에서 gcc 4.4입니다.
내 이해는 C ++에서 정수 유형 인 한 클래스 내에서 정적 const 멤버를 정의 할 수있는 것입니다.
당신은 항상 맞습니다. 클래스 선언에서 정적 정수를 초기화 할 수 있습니다.
흥미롭게도 std :: min에 대한 호출을 주석 처리하면 코드가 잘되고 연결됩니다 (이전 행 회의 test :: N이 참조 되었음에도 불구하고).
무슨 일이 일어나고 있는지 아십니까?
std :: min은 매개 변수를 const 참조로 사용합니다. 값을 기준으로 필요하기 때문에 문제는 없지만 참조가 필요합니다.
다음은 장 / 구절입니다.
9.4.2 / 4 - 경우 static
데이터 부재이다 const
정수 또는 const
열거-type 클래스 정의의 선언이 지정 일정한 이니셜 적분 상수 식 (5.19)한다. 이 경우 멤버는 정수 상수 식에 나타날 수 있습니다. 멤버는 프로그램에서 사용되는 경우 네임 스페이스 범위에서 정의되어야하며 네임 스페이스 정의 범위에서 이니셜 라이저가 포함 되지 않습니다 .
가능한 해결 방법은 Chu의 답변을 참조하십시오.
그의 C ++ FAQ에있는 Bjarne Stroustrup의 예 는 당신이 사용하는 경우에만 정의가 필요합니다.
class AE {
// ...
public:
static const int c6 = 7;
static const int c7 = 31;
};
const int AE::c7; // definition
int f()
{
const int* p1 = &AE::c6; // error: c6 not an lvalue
const int* p2 = &AE::c7; // ok
// ...
}
그는 "정적 멤버의 주소를 사용할 수 있습니다 (클래스 외 정의가있는 경우에만)"라고 말합니다 . 상호 작동 할 것을 제안합니다. min 함수가 어떻게 든 뒤에서 주소를 호출 할 수 있습니다.
수행하는 또 다른 방법은 정수 유형의 경우 상수를 클래스에서 열거 형으로 정의하는 것입니다.
class test
{
public:
enum { N = 10 };
};
단지 int가 아닙니다. 그러나 클래스 선언에서 값을 정의 할 수 없습니다. 당신이 가지고있는 권한 :
class classname
{
public:
static int const N;
}
.h 파일에 다음이 될 것입니다.
int const classname::N = 10;
.cpp 파일에서.
문제를 해결하는 또 다른 방법은 다음과 같습니다.
std::min(9, int(test::N));
(나는 Crazy Eddie의 대답이 문제가 존재하는 이유를 설명 할 생각합니다.)
C ++ 11부터 다음을 사용할 수 있습니다.
static constexpr int N = 10;
이것은 이론적으로 여전히 .cpp 파일에서 상수를 정의해야하지만 그 주소를 사용하지 않는 N
한 컴파일러 구현에서 오류가 발생할 가능성은 거의 없습니다.)
C ++에서는 정적 const 멤버를 클래스 내부에 정의 할 수 있습니다.
아니요, 3.1 §2에서는 다음과 같이 말합니다.
선언은 함수의 본문 (8.4)을 지정하지 않고 함수를 선언 하지 않는 한 정의이며 , 외부 지정자 (7.1.1) 또는 연결 사양 (7.5)을 포함하고 이니셜 라이저 나 함수 본문이 없으며 정적 데이터를 선언합니다. 클래스 정의 (9.4)의 멤버 , 클래스 이름 선언 (9.1), opaque-enum-declaration (7.2) 또는 typedef 선언 (7.1.3), using-declaration (7.3. 3) 또는 사용 지시문 (7.3.4).
'IT' 카테고리의 다른 글
Pandas DataFrame에서 "Unnamed : 0"열을 제거하는 방법은 무엇입니까? (0) | 2020.08.19 |
---|---|
배열 변수의 크기가 main에서와 동일하지 않은 이유는 무엇입니까? (0) | 2020.08.19 |
동일한 컴퓨터에서 여러 버전의 Google 크롬을 사용할 수 있습니까? (0) | 2020.08.19 |
오류 : 삭제 된 기능 사용 (0) | 2020.08.19 |
Asyncio.gather 대 asyncio.wait (0) | 2020.08.19 |