2009-12-21 9 views
8

개체에 변경되지 않을 특성이 있고 해당 기능을 통해 필요할 때 가장 좋은 옵션이 무엇인지 결정하려고합니다.전용 멤버 : 정적 const 대 단지 const

  1. const 정적 멤버
  2. 헌장 회원

그것은 정적 멤버가 변경 될 수있는 변수를 가지고있다 진짜 이유처럼 날 것으로 보인다, 따라서 다른 모든 개체에 영향을 같은 학급. 그러나 정적 const 멤버가되기 위해 사람들이 "invariants"클래스를 추천하도록했습니다. 클래스 상수를 설정하는 데 권장되는 접근 방식 및 이유에 대한 통찰력을 찾고 있습니다.

답변

15

"변경되지 않음"이 정확하지 않습니다. 여기에서 가장 중요한 질문은 클래스의 다른 객체가 이들 const 멤버의 다른 값을 가질 필요가 있는지 (객체의 수명 기간 동안 변경되지 않더라도) 또는 모든 객체가 동일한 값을 사용 (공유)해야하는지 여부입니다.

값이 클래스의 모든 개체에서 동일하면 당연히 클래스의 static const이어야합니다.

다른 개체가 다른 값을 필요로하는 경우 정적이 아닌 const 구성원이어야합니다.

+0

는 "변경되지 않습니다"나는 값이 클래스의 모든 객체에 대해 동일 의미했다. – trikker

+3

그런 경우에는'static const'를하지 않을 이유가 없습니다. 정적이 아닌 const는 (특정/이국적인 경우를 제외하고) 잘 작동하지만 불필요하게 낭비되는 메모리 낭비를 초래합니다. – AnT

+0

네, 그게 제가 가진 요점입니다. – trikker

14

const 구성원이 인스턴스별로 변경되지 않을 경우 구성원을 사용해야합니다. 해당 구성원이 클래스 단위로 변경되지 않을 경우 static const 구성원을 사용해야합니다. 즉, 얼마나 많은 인스턴스를 만들지에도 const 구성원은 특정 인스턴스에 대해서만 상수 임에 반해 static const 구성원은 모든 인스턴스간에 고정되어 있습니다.

그게 당신이 찾고있는 것인지는 확실하지 않습니다. 그게 단지 그들이 어떻게 행동하는지에 대한 설명 일 뿐이지 만, 저는 그것이 다소 도움이되기를 바랍니다.

+0

라고 설명했습니다. –

1

일반 const 멤버가 더 많은 메모리를 차지하게되는 한 가지 이유가 있습니다. 즉, 생성 한 클래스의 각 객체에 대해 하나의 const 멤버 객체가 해당 객체에 포함되어 초기화됩니다.

정적 const 멤버 인 경우 생성하는 클래스의 개체 수에 관계없이 하나의 개체 만 만들어지고 초기화되며 모든 클래스 개체는 동일한 개체를 공유합니다.

여러 방법으로 컴파일하고 여러 객체를 만들고 printf ("% p", & theConstMemberObject)를 수행하면 ... 정적 인 경우 모두 동일한 포인터 값을 인쇄합니다. 정적이지 않은 경우에는 각각 고유 한 객체가 있으므로 각각 다른 포인터 값을 인쇄합니다.

0

멤버 변수를 정적 const로 만들 것입니다. 변경되지 않은 상태에서 클래스의 모든 인스턴스에서 공유하는 동일한 복사본을 다시 사용할 수 있기 때문입니다. 각 인스턴스는 상수 값의 자체 (동일한) 복사본을 가지고 있습니다.

당신은 컴파일러가이 최적화를 수행 할만큼 똑똑 할 것이라고 기대할 수 있습니다. 그래도 들어가기 좋은 습관입니다.

+2

const 멤버 변수는 생성자에서 초기화 될 수 있으므로 클래스의 다른 인스턴스에 따라 달라질 수 있습니다. – danio

+1

컴파일러가 수행 할 수있는 작업에주의해야합니다. @danio가 지적한 것처럼, 헤더가 다른 컴파일 단위에서 재사용되는 경우 컴파일러는 값이 공유됨을 알 수있는 컴파일 단위가 하나뿐입니다. 호환 가능한 메모리 레이아웃을 정의해야하는 많은 컴파일 장치가 있습니다. 아는 사람은 다른 모든 컴파일 단위에서 코드를 깨뜨리기 때문에 메모리 레이아웃을 변경할 수 없습니다. –

0

내 선호도는 항상 const 회원보다 더 많은 커플 링을 생성하는 것처럼 보일 수 있으므로 static const 회원을 사용하면 안됩니다. 때로는 혼란 스럽다.final 클래스가 2 개의 수퍼 클래스 (1 클래스는 상속 됨 public에서 상속 받음)에서 상속받은 최종 상속 계층은 new, malloc, calloc 등을 통해 동적 메모리 영역을 가리키는 static const 멤버를 정의하면 double free이됩니다. 오류.

여기에 간단한 다이아몬드 상속 상황 여기

ray:~ ray$ ./multiinheritance 
Base() called 
Derived1() called 
Base() called 
Derived2() called 
Final() called 
~Final() called 
~Derived2() called 
~Base() called 
freeing memory 
~Derived1() called 
~Base() called 
freeing memory 
multiinheritance(475) malloc: *** error for object 0x100150: double free 
*** set a breakpoint in malloc_error_break to debug 
ray:~ ray$ 

의 출력 코드 것입니다 작성자 :

#include <iostream> 
#include <string> 

class Base { 
public: 
    Base() { 
     std::cout << "Base() called " << std::endl; 
    } 
    virtual ~Base() { 
     std::cout << "~Base() called" << std::endl; 
     std::cout << "freeing memory" << std::endl; 
     delete i; 
    } 
    static const int* i; 
}; 

const int* Base::i = new int[5]; 

class Derived1 : virtual public Base { 
public: 
    Derived1() { 
     std::cout << "Derived1() called " << std::endl; 
    } 
    virtual ~Derived1() { 
     std::cout << "~Derived1() called" << std::endl; 
    } 
}; 
class Derived2 : public Base { 
public: 
    Derived2() { 
     std::cout << "Derived2() called " << std::endl; 
    } 
    virtual ~Derived2() { 
     std::cout << "~Derived2() called" << std::endl; 
    } 
}; 

class Final: public Derived1, public Derived2 { 
public: 
    Final() { 
     std::cout << "Final() called" << std::endl; 
    } 
    ~Final() { 
     std::cout << "~Final() called" << std::endl; 
    } 
}; 

int main(int argc, char** argv) { 
    Final f; 
return 0; 
} 
+0

그 출력을 가져온 코드를 게시해야합니다. 그렇지 않으면 쓸모가 없습니다. 그리고 어쨌든 유용 할 것이라고 확신하지는 않습니다. 왜냐하면'const'와'static const'가 어디에 차이가 나는지 알지 못하기 때문입니다. 설명에서 정적 (static) 대 동적 (non-static) 동적 메모리 할당과 삭제에 대한 문제와 비슷하게 들립니다. –

+0

@dribeas, 나는 때때로'const'와'static const'를 다중/가상 상속과 혼합하는 것을 설명하려고 시도하고있었습니다 –

관련 문제