2009-11-19 4 views
2

수십 개의 개인 멤버 변수가있는 클래스가 있다고 가정 해보십시오.다른 큰 클래스로 구성된 클래스 문제

class Bar 
{ 
private: 
    // some instances of other classes of about the same complexity as Foo 
    Foo m_foo; 
}; 

그래서 바는 기본적으로 클래스 :

class Foo 
{ 
public: 
    int GetA() const { return m_a; } 
     : 
    int GetZ() const { return m_z; } 

    void SetA(int val) { m_a = val; } 
     : 
    void SetZ(int val) { m_z = val; } 

private: 
    int m_a; 
     : 
    int m_z 
}; 

이제 우리는 (다른 것들 사이에) 푸로 구성되어 두 번째 클래스를 가지고 각 멤버 변수는 공개 게터와 세터 기능이 있습니다 하나의 엔티티에서 다른 클래스의 인스턴스를 함께 바인딩합니다.

Bar의 인스턴스를 전달하는 함수는 getter 및 setter 함수를 호출 할 수 있도록 m_foo에 액세스하려고합니다. 효과적인 C++ (제 3 판 - 항목 # 28)의 Scott Meyers 조언을 염두에두고 m_foo에 '핸들'을 반환하는 항목을 추가하는 것을 꺼립니다.

Foo& GetFoo() const { return m_foo; } // dubious const, I know 

바의 모든 단일 getter 및 setter를 복제하는 것 외에 다른 옵션이 있습니까?

'm_foo'공개를하기에 충분히 게으른 일부 기존 코드로 작업하고 있습니다! 그러나 Scott의 조언 (이 경우 항목 # 22 - "데이터 멤버를 비공개로 선언")과 다른 점이 있습니다.

이 바인딩에서 벗어날 수 있습니까?

+0

const가 불투명 할뿐만 아니라 잘못되었습니다. m_foo는 해당 메소드의 컨텍스트에서 const가됩니다. –

답변

2

데이터 멤버를 공개로 설정해야합니다.

당신이 설명하는 바와 같이 Bar getters와 setter를 제공하면 이미 개념적으로 공개됩니다. 이것은 getter가 참조를 반환하는 모든 getter/setter 쌍에 유사하게 적용됩니다. (이전/후크를 포함 할 수 있지만 캡슐화와는 다른 문제는 제외)

+2

Yeesh, 여기 사람들은 아래쪽 투표에 만족합니다. 회원을 공개 할 때 당신이하고있는 일을 잘 알고있는 한 아무 문제가 없습니다. 그것이 필요하다면 되돌아 가서 캡슐화하기가 어렵지 않습니다. –

+0

필자는 getter 접근법 인'const Foo & GetFoo() const;'와'Foo & GetFoo();'를 주장 할 것입니다. 이런 식으로 (로그와 같이) 메소드를 측정하여 버그를 추적 할 수 있습니다. 중단 점도 설정해야하지만 개념적으로는 동일합니다. –

+0

@Matthieu M 그게 전반적인 더 나은 방법이라고 당신에게 동의 하겠지만, 대중의 제안이 너무 낮아서 투표 할 자격이 없다고 생각하지 않습니다. 얼마나 나쁜지에 상관없이, 당신이 동의하지 않는 것뿐만 아니라 잘못 된 것에 대해서는 아래로 투표해야합니다. 공개 회원들에게 아무런 문제가 없으며, 그들은 완벽하게 합법적입니다. 그들은 단지 몇 가지 사전 고려가 필요하며 특정 상황이 발생하면 앞으로 약간의 추가 작업으로 이어질 수 있습니다. –

0

어쨌든 getter와 setter를 사용하는 대형 클래스가 있으면 해당 객체에 대한 참조를 반환하는 데 문제가 있다고 생각하지 않습니다 결국, 사이에 레이어가 남아 있습니다. 기본적으로 Foo에서 설정/가져 오는 것을 제어 할 수 있습니다.

OTOH 아마도 공개 속성이 많아서 수업을 설계한다면 어쩌면 디자인을 재검토해야할까요? 클래스에서 더 많은 것들을 다루기가 더 어려울 수 있습니다.

EDIT : 공개 멤버의 데이터 구조를 변경하여 일종의지도에 배치 할 수 있습니까? 그런 식으로 적어도 약간의 글을 저장할 것입니다. :-)

get("propertyname") 
set("propertyname",value) 
0

는 개인 멤버 변수의 수십 클래스를 상상해보십시오. 각 멤버 변수에는 공용 getter 및 setter 함수가 있습니다.

음, 나는하지 않을 것입니다. 왜 이것이 나쁜 생각인지 here을 읽어보십시오.

+0

음 ... 재미있는 기사지만, 고맙습니다. 몇 가지 이유 : 유지 보수, 디버깅 (조건부 중단 점을 만드는 것보다 코드에서 중단 점을 설정하는 것이 훨씬 쉽습니다.) 및 데이터 구조 최적화. – BostonLogan

+0

@BostonLogan : 잘 모르겠습니다. 이 기사는 getter/setter로 가득 찬 클래스는 클래스가 아니라 단지 getter/setter의 영광스러운 어셈블리라고 주장합니다. 그것은 추상화 수준과 OO가 실제로하는 것에 관한 것입니다. 이것은 디버깅과 관련이 없으며 유지 보수와 관련하여 구조화 된 프로그래밍에 비해 거의 또는 전혀 이점이 없습니다. – sbi

+0

Sbi, 나는 "정의 된 행동 없음"이라는 준 클래스에 대한 저자의 정의를 보완 할 것이다. 즉, 단순한 데이터 구조가 할 수있는 것 이상을 수행하지 않는다. 그렇다면 공개적으로 용기가 있어야한다. 그러나 클래스의 객체가 동작을 나타낼 수 있고이 동작이 상태에 따라 다르면 상태는 개인이되어야하며 설정자 만 수정할 수 있어야합니다. – BostonLogan

0

아니요. foo에서 모든 getter 또는 setter에 대해 전달 getter 및 setter를 만들 수 있습니다. foo 인스턴스를 public으로 만들거나 foo에 대한 getter 및 setter를 만들 수 있습니다.

일반적으로 이런 종류의 상황에 직면했을 때 나는 foo와 bar의 데이터를 캡슐화 한 이유를 다시 확인하는 것이 좋습니다.foo를 여러 클래스로 분해 한 다음 foo 데이터의 각 부분에 액세스해야하는 함수를 적절한 클래스로 메소드로 이동할 수있는 경우가 종종 있습니다. 이것은 실제로 클래스의 private 멤버 변수 인 변수를 가져오고 setter와 getter의 필요성을 제거합니다. 이것이 객체 지향 프로그래밍이 작동하는 방식입니다.

레거시 코드에서이를 수행하는 좋은 방법은 Martin Fowler의 Refactoring을 참조하십시오.

관련 문제