IT story

보호 된 멤버 변수를 사용해야합니까?

hot-time 2020. 8. 28. 08:00
반응형

보호 된 멤버 변수를 사용해야합니까?


보호 된 멤버 변수를 사용해야합니까? 장점은 무엇이며 이로 인해 어떤 문제가 발생할 수 있습니까?


보호 된 멤버 변수를 사용해야합니까?

상태를 숨기는 것에 대해 얼마나 까다로운 지에 따라 다릅니다.

  • 내부 상태의 유출을 원하지 않는 경우 모든 멤버 변수를 private으로 선언하는 것이 좋습니다.
  • 하위 클래스가 내부 상태에 액세스 할 수 있다는 사실에 관심이 없다면 protected로 충분합니다.

개발자가 함께 와서 클래스를 하위 클래스로 지정하면 완전히 이해하지 못하기 때문에 엉망이 될 수 있습니다. 공용 인터페이스가 아닌 개인 멤버를 사용하면 작업이 수행되는 방식에 대한 구현 특정 세부 사항을 볼 수 없으므로 나중에 변경할 수있는 유연성을 제공합니다.


요즘 일반적인 느낌은 파생 클래스와 그 기반 사이에 과도한 결합을 유발한다는 것입니다.

보호 된 메서드 / 속성에 비해 특별한 이점이 없으며 (한때 약간의 성능 이점이있을 수 있음), 매우 깊은 상속이 유행하던 시대에 더 많이 사용되었지만 현재는 그렇지 않습니다.


일반적으로 의도적으로 공개 된 것으로 간주되지 않은 내용은 비공개로 설정합니다.

파생 클래스에서 해당 개인 변수 또는 메서드에 액세스해야하는 상황이 발생하면 개인에서 보호로 변경합니다.

이것은 거의 발생하지 않습니다. 대부분의 상황을 모델링하는 데 특히 좋은 방법이 아니기 때문에 저는 상속의 팬이 아닙니다. 어쨌든 계속해서 걱정하지 마십시오.

나는 이것이 대부분의 개발자들에게 괜찮다고 말하고 싶습니다 (그리고 아마도 그것에 대해 최선의 방법 일 것입니다).

문제의 간단한 사실은 다른 개발자가 1 년 후 와서 개인 멤버 변수에 대한 액세스가 필요하다고 결정하면 코드를 편집하고 보호 된 것으로 변경하고 비즈니스를 계속할 것입니다.

이에 대한 유일한 예외는 바이너리 dll을 블랙 박스 형태로 제 3 자에게 배송하는 사업에있는 경우입니다. 이것은 기본적으로 Microsoft, 'Custom DataGrid Control'공급 업체 및 확장 성 라이브러리와 함께 제공되는 몇 가지 다른 대형 앱으로 구성됩니다. 당신이 그 범주에 속하지 않는 한, 이런 종류의 것에 대해 걱정하는 데 시간 / 노력을 소비 할 가치가 없습니다.


일반적으로 보호 된 멤버 변수를 사용하는 코드를 완전히 제어 할 수있는 드문 경우로 유지합니다. 공용 API를 만드는 경우 절대로하지 않습니다. 아래에서 멤버 변수를 개체의 "속성"이라고합니다.

다음 은 private-with-accessors가 아닌 멤버 변수를 protected로 만든 후에 슈퍼 클래스 수행 할 수없는 작업입니다.

  1. 속성을 읽을 때 즉시 값을 느리게 만듭니다. 보호 된 getter 메서드를 추가하면 값을 느리게 생성하고 다시 전달할 수 있습니다.

  2. 속성이 수정되거나 삭제 된시기를 알 수 있습니다. 수퍼 클래스가 해당 변수의 상태에 대해 가정 할 때 버그가 발생할 수 있습니다. 변수에 대해 보호 된 setter 메서드를 만들면 해당 제어가 유지됩니다.

  3. 변수를 읽거나 쓸 때 중단 점을 설정하거나 디버그 출력을 추가합니다.

  4. 해당 멤버 변수를 사용할 수있는 모든 코드를 검색하지 않고 이름을 바꿉니다.

일반적으로 보호 된 멤버 변수를 만들 것을 권장하는 드문 경우라고 생각합니다. 몇 시간 후에 보호 변수를 수정 한 다른 코드에서 버그를 추적하는 것보다 게터 / 세터를 통해 속성을 노출하는 데 몇 분을 보내는 것이 좋습니다. 뿐만 아니라 종속 코드를 손상시키지 않고 향후 기능 (예 : 지연로드)을 추가하지 않도록 보장합니다. 지금하는 것보다 늦게하는 것이 더 어렵습니다.


디자인 수준에서는 보호 된 속성을 사용하는 것이 적절할 수 있지만 구현을 위해 접근 자 / 변이 자 메서드가 아닌 보호 된 멤버 변수에 매핑하는 이점이 없습니다.

보호 된 멤버 변수는 기본 클래스 클래스의 내부 상태에 대한 클라이언트 코드 (하위 클래스) 액세스를 효과적으로 허용하기 때문에 상당한 단점이 있습니다. 이것은 기본 클래스가 불변성을 효과적으로 유지하는 것을 방지합니다.

같은 이유로 보호 된 멤버 변수는 상수가 보장되거나 단일 스레드로 제한되지 않는 한 안전한 다중 스레드 코드 작성을 훨씬 더 어렵게 만듭니다.

접근 자 / 변이 자 메서드는 유지 관리 중에 훨씬 더 많은 API 안정성과 구현 유연성을 제공합니다.

또한 OO 순수 주의자라면 객체는 상태를 읽거나 설정하지 않고 메시지를 보내 공동 작업 / 소통합니다.

그 대가로 그들은 거의 장점을 제공하지 않습니다. 다른 사람의 코드에서 반드시 제거하지는 않지만 직접 사용하지는 않습니다.


나에게 중요한 문제는 일단 변수를 보호 하면 하위 클래스가 항상 범위를 벗어날 수 있기 때문에 클래스의 어떤 메서드도 범위 내에있는 값에 의존 하도록 허용 할 수 없다는 것입니다.

예를 들어, 렌더링 가능한 객체의 너비와 높이를 정의하는 클래스가 있고 해당 변수를 보호하는 경우 가로 세로 비율 (예 : 가로 세로 비율)에 대한 가정을 할 수 없습니다.

비판적으로 저는 코드가 라이브러리로 출시 된 순간부터 이러한 가정을 할 수 없습니다. 종횡비를 유지하기 위해 setter를 업데이트하더라도 변수가 setter를 통해 설정되거나 다음을 통해 액세스된다는 보장이 없기 때문입니다. 기존 코드의 게터.

그들은 어느 변수 값을 적용 할 수 없기 때문에도 내 클래스의 서브 클래스는, 그 보장을 선택할 수 있습니다 그 자신의 서브 클래스의 전체 지점의 경우에도 .

예로서:

  • 너비와 높이가 보호 된 변수로 저장되는 사각형 클래스가 있습니다.
  • 내 컨텍스트 내에서 명백한 하위 클래스는 "DisplayedRectangle"클래스입니다. 유일한 차이점은 그래픽 디스플레이에 대해 너비와 높이를 유효한 값으로 제한한다는 것입니다.
  • 하지만 지금은 불가능합니다. 내 DisplayedRectangle 클래스 해당 값을 진정으로 제한 할 수 없기 때문에 하위 클래스가 DisplayedRectangle로 처리되는 동안 값을 직접 재정의 할 수 있기 때문입니다.

변수를 비공개로 제한하면 setter 또는 getter를 통해 원하는 동작을 적용 할 수 있습니다.


대부분의 경우 protected를 사용하는 것은 잘못 설계된 파생 클래스에 의해 잘 분해 될 수있는 클래스의 캡슐화를 다소 깨뜨리기 때문에 위험합니다.

하지만 좋은 예가 하나 있습니다. 일종의 일반 컨테이너를 사용할 수 있다고 가정 해 보겠습니다. 내부 구현과 내부 접근자가 있습니다. 그러나 데이터에 대한 공개 액세스 권한을 최소한 3 개 (map, hash_map, vector-like) 제공해야합니다. 그러면 다음과 같은 것이 있습니다.

template <typename T, typename TContainer>
class Base
{
   // etc.
   protected
   TContainer container ;
}

template <typename Key, typename T>
class DerivedMap     : public Base<T, std::map<Key, T> >      { /* etc. */ }

template <typename Key, typename T>
class DerivedHashMap : public Base<T, std::hash_map<Key, T> > { /* etc. */ }

template <typename T>
class DerivedVector  : public Base<T, std::vector<T> >        { /* etc. */ }

나는 이런 종류의 코드를 한 달 전에 사용했습니다 (따라서 코드는 메모리에서 가져온 것입니다). 몇 가지 생각을 한 후, 제네릭 Base 컨테이너는 추상 클래스 여야한다고 생각합니다. 비록 그것이 꽤 잘 살 수 있더라도 Base를 직접 사용하는 것은 매우 고통 스러울 것이기 때문에 금지되어야합니다.

Summary Thus, you have protected data used by the derived class. Still, we must take int o account the fact the Base class should be abstract.


In short, yes.

Protected member variables allow access to the variable from any sub-classes as well as any classes in the same package. This can be highly useful, especially for read-only data. I don't believe that they are ever necessary however, because any use of a protected member variable can be replicated using a private member variable and a couple of getters and setters.


Just for the record, under Item 24 of "Exceptional C++", in one of the footnotes, Sutter goes "you would never write a class that has a public or protected member variable. right? (Regardless of the poor example set by some libraries.)"


For detailed info on .Net access modifiers go here

There are no real advantages or disadvantages to protected member variables, it's a question of what you need in your specific situation. In general it is accepted practice to declare member variables as private and enable outside access through properties. Also, some tools (e.g. some O/R mappers) expect object data to be represented by properties and do not recognize public or protected member variables. But if you know that you want your subclasses (and ONLY your subclasses) to access a certain variable there is no reason not to declare it as protected.

참고URL : https://stackoverflow.com/questions/37011/should-you-ever-use-protected-member-variables

반응형