code

C ++에서 클래스 범위 상수를 선언 / 정의 할 위치는 어디입니까?

codestyles 2020. 12. 9. 08:11
반응형

C ++에서 클래스 범위 상수를 선언 / 정의 할 위치는 어디입니까?


C ++의 다양한 상수 선언 및 정의 옵션의 장점 / 단점에 대해 궁금합니다. 가장 오랫동안 클래스 정의 전에 헤더 파일의 맨 위에 선언했습니다.

//.h
const int MyConst = 10;
const string MyStrConst = "String";
class MyClass {
...
};

이로 인해 글로벌 네임 스페이스가 오염되지만 (나쁜 것으로 알고 있지만 왜 나쁜지에 대한 세탁 목록을 찾지 못함) 상수는 여전히 개별 번역 단위로 범위가 지정되므로이 헤더를 포함하지 않는 파일 이러한 상수에 액세스 할 수 없습니다. 그러나 다른 클래스가 동일한 이름의 상수를 정의하면 이름 충돌이 발생할 수 있습니다. 이는 리팩토링 될 수있는 영역의 좋은 표시 일 수 있으므로 나쁜 것은 아닙니다.

최근에 클래스 정의 자체 내부에 클래스 별 상수를 선언하는 것이 더 나을 것이라고 결정했습니다.

//.h
class MyClass {
    public:
         static const int MyConst = 10;
...
    private:
         static const string MyStrConst;
...
};
//.cpp
const string MyClass::MyStrConst = "String";

상수의 가시성은 상수가 클래스 내부에서만 사용되는지 아니면 클래스를 사용하는 다른 객체에 필요한지에 따라 조정됩니다. 이것이 제가 생각하는 최선의 선택입니다. 주로 내부 클래스 상수를 클래스에 대해 비공개로 유지할 수 있고 공용 상수를 사용하는 다른 클래스는 상수의 소스에 대해 더 자세한 참조를 가질 수 있기 때문입니다 (예 : MyClass : : MyConst). 또한 전역 네임 스페이스를 오염시키지 않습니다. cpp 파일에서 비 통합 초기화가 필요하다는 단점이 있지만.

또한 다른 클래스에 상수가 필요하지만 전체 클래스 정의가 필요한 경우를 대비하여 상수를 자체 헤더 파일로 이동하고 네임 스페이스로 래핑하는 것도 고려했습니다.

아직 고려하지 않은 의견과 다른 옵션을 찾고 있습니다.


정수가 아닌 상수를 정적 클래스 멤버로 선언하는 것이 "cpp 파일에서 정수가 아닌 초기화를 요구하는 데 해를 끼친다"는 주장은 정확히 견고하지 않습니다. cpp 파일에 정의가 필요하지만 "손상"이 아니라 의도의 문제입니다. constC ++의 네임 스페이스 수준 개체에는 기본적으로 내부 연결이 있습니다. 즉, 원래 변형에서 선언이

const string MyStrConst = "String"; 

다음과 같다

static const string MyStrConst = "String"; 

즉, MyStrConst이 헤더 파일이 포함 된 모든 번역 단위에서 독립적 인 개체를 정의합니다 . 알고 계십니까? 이것이 당신의 의도였습니까?

어쨌든 모든 번역 단위에 별도의 개체가 특별히 필요 하지 않은 경우 MyStrConst원래 예제에서 상수 선언은 좋은 방법이 아닙니다. 일반적으로 헤더 파일에 정의되지 않은 선언 만 넣습니다.

extern const string MyStrConst; 

cpp 파일에 정의를 제공합니다.

const string MyStrConst = "String";

따라서 전체 프로그램이 동일한 상수 객체를 사용하는지 확인합니다. 즉, 정수가 아닌 상수의 경우 일반적인 관행은 cpp 파일에 정의하는 것입니다. 따라서 어떻게 선언하든 (클래스에서 또는 밖으로) 일반적으로 cpp 파일에서 정의해야하는 "손상"을 처리해야합니다. 물론 위에서 말했듯이 네임 스페이스 상수를 사용하면 첫 번째 변형에있는 것을 벗어날 수 있지만 이는 "지연 코딩"의 예일뿐입니다.

어쨌든 문제를 지나치게 복잡하게 만들 이유는 없다고 생각합니다. 상수에 클래스에 대한 명백한 "부착"이 있으면 클래스 멤버로 선언해야합니다.

PS 접근 지정자 ( public, protected, private)를 제어하지 가시성 이름을. 액세스 가능성 만 제어합니다 . 이름은 어떤 경우에도 계속 표시됩니다.


누군가 (예 : 사용하는 라이브러리의 작성자)가 MyConst다른 목적으로 이름을 사용하려고 할 수 있기 때문에 글로벌 네임 스페이스의 오염은 좋지 않습니다 . 이로 인해 심각한 문제가 발생할 수 있습니다 (함께 사용할 수없는 라이브러리 등).

두 번째 솔루션은 상수가 단일 클래스에 연결된 경우 분명히 가장 좋습니다. 그렇게 쉽지 않은 경우 (프로그램의 클래스와 연결되지 않은 물리적 또는 수학 상수를 생각해보십시오) 네임 스페이스 솔루션이 그보다 낫습니다. BTW : 이전 C ++ 컴파일러와 호환되어야하는 경우 일부 컴파일러는 헤더 파일에서 통합 초기화를 사용할 수 없음을 기억하십시오 enum.이 경우 에는 C ++ 파일에서 초기화하거나 이전 트릭을 사용해야합니다 .

상수에 대한 더 나은 옵션은 없다고 생각합니다. 적어도 지금은 생각할 수 없습니다.


글로벌 네임 스페이스를 오염시키는 것은 분명히 나쁘다. 헤더 파일을 포함하면 해당 헤더에 선언 된 상수와 이름 충돌을 발생 시키거나 디버그하고 싶지 않습니다. 이러한 유형의 오류는 정말 실망스럽고 때로는 진단하기가 어렵습니다. 예를 들어, 헤더에 정의 된 프로젝트에 링크해야했습니다.

#define read _read

상수가 네임 스페이스 오염 인 경우 이는 네임 스페이스 핵 폐기물입니다. 이것의 표현은 _read 함수를 놓친 것에 대해 불평하는 일련의 매우 이상한 컴파일러 오류 였지만 해당 라이브러리에 연결할 때만 발생했습니다. 결국 우리는 읽기 기능의 이름을 다른 것으로 변경했습니다. 어렵지는 않지만 불필요해야합니다.

Your second solution is very reasonable as it puts the variable into scope. There's no reason that this has to be associated with a class, and if I need to share constants among classes I'll declare constants in their own namespace and header file. This isn't great for compile-time, but sometimes it's necessary.

I've also seen people put constants into their own class, which can be implemented as a singleton. This to me seems work without reward, the language provides you some facilities for declaring constants.


You can declare them as globals in the c++ file, as long as they are not referenced in the header. Then they are private to that class and won't pollute the global namespace.


Personally I use your second approach; I've used it for years, and it works well for me.

From a visibility point I would tend to make the private constants file level statics as nobody outside the implementation file needs to know they exist; this helps prevent chain reaction recompiles if you need to change their names or add new ones as their name scope is the same as their usage scope...


If only one class is going to use these constants, declare them as static const inside the class body. If a bunch of related classes are going to use the constants, declare them either inside a class/struct that only holds the constants and utility methods or inside a dedicated namespace. For example,

namespace MyAppAudioConstants
{
     //declare constants here
}

If they are constants used by the whole application (or substantial chunks of it), declare them inside a namespace in a header that is (either implicitly or explicitly) included everywhere.

namespace MyAppGlobalConstants
{
    //declare constants here
}

don't pollute global namespace, pollute local.

namespace Space
  {
  const int Pint;
  class Class {};
  };

But practically...

class Class
  {
  static int Bar() {return 357;}
  };

참고URL : https://stackoverflow.com/questions/2043493/where-to-declare-define-class-scope-constants-in-c

반응형