2017-11-01 2 views
2

저는 커다란 C++ 프로젝트를 사용하여 제조 공정을 자동화하는 제조 공장에서 일합니다.중첩 클래스의 C++ 릴레이 멤버 함수?

필자는 불필요하게 길게 코드를 작성하는 것으로 보이는 특정 사례를 보았으며이 연습이 사용되는 구체적인 이유가 있는지 궁금해하고있었습니다.

이 연습을 보여주는 간단한 예제는 아래를 참조하십시오.

첫 번째 파일 :

class A { 

private: 
    int a; 

public: 
    int get_a() 
    { return a; } 

    void set_a(int arg) 
    { a = arg; } 
}; 

두 번째 파일 :

class B { 

private: 
    int b; 

public: 
    int get_b() 
    { return b; } 

    void set_b(int arg) 
    { b = arg; } 
}; 

세 번째 파일 :

class C { 

private: 
    A obj1; 
    B obj2; 

public: 
    int get_a() 
    { return obj1.get_a(); } 

    int get_b() 
    { return obj2.get_b(); } 

    void set_a(int arg) 
    { obj1.set_a(arg); } 

    void set_b(int arg) 
    { obj2.set_b(arg); } 
}; 

이 크게 감소 할 수 디자인 철학에 약간의 변화처럼 날 것으로 보인다 제 3 파일의 코드 양. 이런 식으로 뭔가 :

class C { 

public: 
    A obj1; 
    B obj2; 

}; 

AB 클래스는 각 안전하게 점점 자신의 멤버 변수의 설정을 처리하기 때문에 obj1obj2에서, C 클래스 public 멤버 안전하지 않은 될 것 같지 않습니다 수 가졌어요.

나는이 방법은 함수를 호출하는 C 클래스의 인스턴스가 대신 obj.get_a()obj.obj1.get_a() 같은 것을 할 필요가 있다는 것입니다 그 일을 생각할 수있는 유일한 단점하지만이 것보다 불편의 훨씬 적은 것 같아 개인 AB 개체 인스턴스가 C 클래스에 있고 모든 수동 멤버 함수를 "릴레이"해야합니다.

이 간단한 예제에서는 코드가 많지 않지만 우리 회사에서 사용하는이 대형 프로젝트의 경우 말 그대로 수만 개를 추가합니다. 줄의 코드입니다.

내가 누락 된 항목이 있습니까?

+0

getters와 setters는 약간의 냄새가 있지만 원래 개발자가 [Demeter의 법칙] (https://en.wikipedia.org/wiki/Law_of_Demeter)을 적용한 것처럼 보입니다. 거기에 장단점이 있습니다. –

+0

단점은 분명해 보입니다. 더 많은 코드가 추가되었습니다. 죄수 팀은 무엇입니까? (이미 언급 한 것, 즉'obj.obj1.get_a()'과'obj.get_a()') – ImaginaryHuman072889

+0

위키피디아 페이지는 꽤 잘 설명합니다. 감사! – ImaginaryHuman072889

답변

1

많은 이유가있을 수 있습니다. 하나는 다음과 같습니다 :

회원이 a 인 무언가를 수행하는 함수를 작성한다고 가정 해보십시오. 동일한 코드에서 AC을 받아 들일 수 있습니다. 함수는 다음과 같이 수 : 그것은 다른 인터페이스를 가지고 있기 때문에

template <typename T> 
void foo(T& t) { 
    std::cout << " a = " << t.get_a(); 
} 

이것은 당신의 C와 함께 작동하지 않을 것입니다.

캡슐화는 장점이 있지만 캡슐화를위한 캡슐화가 훨씬 더 많은 코드로 이어지고 종종 그 외의 다른 것까지 이끌어가는 것에 동의합니다.

일반적으로 호출 코드가 obj.obj1.get_a()과 같은 것을 작성하도록 강요하는 것은 구현 세부 사항을 나타내므로 권장하지 않습니다. 예를 들어 a 유형을 변경 한 경우 C에는 해당 변경 사항이 전혀 적용되지 않습니다.다른 한편으로, aint에서 double으로 변경되면 인터페이스는 int 인터페이스를 유지하고 일부 변환 (해당되는 경우)을 유지할지 또는 인터페이스를 변경할지 여부를 결정할 수 있습니다.

+0

* 일반적으로 호출 코드가 obj.obj1.get_a()와 같은 것을 작성하도록 강요하는 것은 구현의 세부 사항을 나타 내기 때문에 권장하지 않습니다. * 와우, 좋은 지적, 결코 그렇게 생각하지 않았습니다. C 클래스를 많이 사용하는 코드를 명확하게 만들었습니다. C 클래스 자체가 "오버 헤드"유형 코드를 겉으로 드러내는 것처럼 보입니다. 어쨌든, 당신의 설명은 위대하고 정확히 내가 찾고있는 것이 었습니다. – ImaginaryHuman072889

+1

@ ImaginaryHuman072889 당신의 게시물에있는 코드는 내가 학교에서 겪은 것처럼 보였고, getter와 setter를 사용하는 유일한 이유가 없다는 것을 이해하기까지 수년이 걸렸습니다. 나는 지침을 따르는 이유를 아는 것이 중요하다고 생각합니다. 때로는 따라하기를 원하지 않기 때문입니다.) – user463035818

1

약간의 코드가 추가되지만 중요한 것은 인터페이스입니다. 클래스에는 책임이 있으며, 멤버는 구현 세부 사항을 유지합니다. 내부 객체를 노출하고 사용자에게 "객체 가져 오기, 호출"을 강요하는 경우 사용자를위한 작업을 수행하는 인터페이스를 제공하는 것보다 호출자를 구현에 더 많이 연결합니다. 비유하자면, 개가 걷기를 원할 때 강아지의 다리에 직접 걸어 가지 말라고 명령하지 않습니다. 그 대신 하나는 개에게 명령을 내리고 그 다음에 자신의 다리를 명령합니다.

  • O : 공식적

    Law of Demeter/Wikipedia

    더는 기능 데메테르의 법칙 오브젝트 O의 방법 m 만 오브젝트는 다음과 같은 종류의 방법을 호출 할 수 있어야 자체

  • m 매개 변수
  • m 내에 생성되었거나 인스턴스화 된 모든 개체
  • ,515,
  • O의 직접적인 구성 요소는 특히, 객체가 다른 방법에 의해 반환 부재 객체의 메소드를 호출 피해야 m

의 범위에서, O가

  • 전역 변수 액세스 개체. 필드 식별자로 도트를 사용하는 많은 최신 객체 지향 언어의 경우 법칙은 단순히 "하나의 도트 만 사용"이라고 말할 수 있습니다. 즉, a.b.c.Method() 코드는 a.b.Method()가 사용하지 않는 법을 위반합니다.

  • 관련 문제