private, public 같은 접근 지정자를 설정하는 것은
개발자 마음입니다.
일반적으로 객체지향 언어들에서는 모든 필드(즉, 멤버변수)는 private으로 선언하고 get/set 함수를 만들어 접근하는 것을 원칙으로 합니다
left_node와 right_node는 일반적으로 position의 개념을 포함하므로 흔히 링크드 리스트와 같이 메모리 연결 방식을 사용한다고 가정하면 메모리와 관련된 오류가 발생할 확률이 높습니다. 그러므로 public으로 선언해두게 되면 안정성 검사를 하지 않고 바로 접근할 수 있으므로 위험한 코딩이 될 가능성이 높습니다. 그러므로 private로 선언 후 public 접근을 하는 편이 좋다고 생각합니다. 물론 이건 제 생각이고 또 많은 경우 그렇게 한다는 것이지 필수 불가결의 선택은 아닙니다.
getter/setter를 쓰면 외부에서 변경 통로가 하나로 정해진다는 점에서 좋은 점이 생깁니다.
그건 바로 타겟 변수가 바뀌더라도 그것과 getter/setter부분만 고쳐주면 된다는 점입니다.
물론 메서드명 자체가 바뀌면 동일한 수준의 변경이 필요하지만요.
사실 getter/setter를 안썼을때 변수가 외부에서 바뀌는 경우가 생긴다는 지적은 조금 다른 문제가 아닌가 싶습니다.
setter가 protected나 private가 아닌 public으로 존재할 때(즉, 외부에서 접근이 가능할 때), 이 변수의 값은 언제든지 변경될 위험이 따르기 때문이죠.
윗분의 답변을 읽어보니 제가 문장력이 짧아서 오해가 있으셨던 것 같습니다.
질문자님께서 제 말뜻을 잘못 이해하셨을까봐 조금 더 보충하여 답변을 올립니다.
제가 전달하고자 했던 외부에서의 갱신을 안정적이라는 말의 뜻은
변수로의 직접적인 할당보다 안정적인 방법을 취할 수 있다는 것입니다.
예를들어 아래와 같은 클래스가 있다면
class BadClass
{
public:
int pub_prime_number;
};
이 클래스는 pub_prime_number라는 필드를 가지는 클래스로 클래스 설계자가 원하는 것은
이와 같은 pub_prime_number라는 필드에 소수에 해당하는 값을 할당하고 처리를 하기를 원합니다.
그런데 지금과 같은 상황이라면 클래스를 사용하는 사람의 입장에서는 소수 뿐 아니라 정수의 범위에 해당하는
모든 수를 할당 할 수 있습니다. 바로 이것이 문제가 됩니다.
클래스 사용자 입장이라면 이러한 문제점을 막기위해(안정적인 코딩을 위해서는)
pub_prime_number에 값을 대입하기전에 대입 할 값을 소수인지 아닌지를 검사하는 코드가 있어야 합니다.
그러나 getter/setter를 사용하면 이러한 문제를 클래스 사용자에게 넘기는 것이 아니라 클래스 설계자가 할 수 있습니다.
class GoodClass
{
private:
int pri_prime_number;
public:
// 편의를 위해 내부에 선언합니다
int getPrimeNum()const
{
// 읽기전용으로 액세스 할 수 있습니다
return pri_prime_number;
}
void setPrimeNum(int arg_number)
{
// 대입이 이루어지기 전에 사전 오류 처리 혹은 예외처리를 클래스 차원에서 할 수 있습니다.
if ( 소수인지 아닌지 검사를 하고 소수일때만 대입 )
pri_prime_number = arg_number;
}
};
GoodClass라는 이름을 붙이고 작성하였지만 오류에 대한 처리를 완벽하게 하지는 않고 있습니다^^;;
그러나 private으로 선언했을때와 public으로 선언했을때의 차이를 명확히 이해하는데는 충분하지 않나 생각합니다.
작성하시는 트리 같은 자료구조에서는 메모리 연산이 많이 이루어질터 getter/setter를 거치느냐 거치지 않느냐의 차이는 큽니다.
예를들면 public으로 선언되었을 때 루트의 왼쪽 자식의 원소값을 읽어오기위해 다음과 같이 접근한다고 가정할때
leftNode가 만약 NULL이나 유효하지 않은 메모리 주소값을 가지고 있다면 다음과 같은 접근은 런타임에서 오류가 발생합니다
tree.leftNode.element // runtime error
그러나 getter를 미리 만들어둔다면
읽어올 값을 리턴하기전에 미리 NULL인지 아닌지를 검사 한 후 런타임 오류를 방지 할 수 있습니다.
물론 이러한 문제는 getter를 사용하지 않고 클래스 사용자 입장에서 처리 할 수도 있겠습니다만,
우리가 어떠한 물건을 구입 할 때, 고장 나지 않고 견고한 제품이 환영받는 것처럼
클래스 또한 설계자가 얼마나 견고하게 만드느냐가 중요하기에 이러한 문제를 사용자에게 돌리기보다는
클래스 설계자가 구현을 하고 사용자는 편하게 사용만 한다는 것입니다. 이것이 객체지향의 철학이기도 하구요..
..
private, public 같은 접근 지정자를 설정하는 것은
개발자 마음입니다.
일반적으로 객체지향 언어들에서는 모든 필드(즉, 멤버변수)는 private으로 선언하고 get/set 함수를 만들어 접근하는 것을 원칙으로 합니다
left_node와 right_node는 일반적으로 position의 개념을 포함하므로 흔히 링크드 리스트와 같이 메모리 연결 방식을 사용한다고 가정하면 메모리와 관련된 오류가 발생할 확률이 높습니다. 그러므로 public으로 선언해두게 되면 안정성 검사를 하지 않고 바로 접근할 수 있으므로 위험한 코딩이 될 가능성이 높습니다. 그러므로 private로 선언 후 public 접근을 하는 편이 좋다고 생각합니다. 물론 이건 제 생각이고 또 많은 경우 그렇게 한다는 것이지 필수 불가결의 선택은 아닙니다.
답변 감사드립니다.. ^^
==================
불가능은 없다. (Nothing is Impossible,, Possible)
==================
불가능은 없다. (Nothing is Impossible,, Possible)
getter/setter를 쓰면
getter/setter를 쓰면 외부에서 변경 통로가 하나로 정해진다는 점에서 좋은 점이 생깁니다.
그건 바로 타겟 변수가 바뀌더라도 그것과 getter/setter부분만 고쳐주면 된다는 점입니다.
물론 메서드명 자체가 바뀌면 동일한 수준의 변경이 필요하지만요.
사실 getter/setter를 안썼을때 변수가 외부에서 바뀌는 경우가 생긴다는 지적은 조금 다른 문제가 아닌가 싶습니다.
setter가 protected나 private가 아닌 public으로 존재할 때(즉, 외부에서 접근이 가능할 때), 이 변수의 값은 언제든지 변경될 위험이 따르기 때문이죠.
윗분의 답변을
윗분의 답변을 읽어보니 제가 문장력이 짧아서 오해가 있으셨던 것 같습니다.
질문자님께서 제 말뜻을 잘못 이해하셨을까봐 조금 더 보충하여 답변을 올립니다.
제가 전달하고자 했던 외부에서의 갱신을 안정적이라는 말의 뜻은
변수로의 직접적인 할당보다 안정적인 방법을 취할 수 있다는 것입니다.
예를들어 아래와 같은 클래스가 있다면
class BadClass
{
public:
int pub_prime_number;
};
이 클래스는 pub_prime_number라는 필드를 가지는 클래스로 클래스 설계자가 원하는 것은
이와 같은 pub_prime_number라는 필드에 소수에 해당하는 값을 할당하고 처리를 하기를 원합니다.
그런데 지금과 같은 상황이라면 클래스를 사용하는 사람의 입장에서는 소수 뿐 아니라 정수의 범위에 해당하는
모든 수를 할당 할 수 있습니다. 바로 이것이 문제가 됩니다.
클래스 사용자 입장이라면 이러한 문제점을 막기위해(안정적인 코딩을 위해서는)
pub_prime_number에 값을 대입하기전에 대입 할 값을 소수인지 아닌지를 검사하는 코드가 있어야 합니다.
그러나 getter/setter를 사용하면 이러한 문제를 클래스 사용자에게 넘기는 것이 아니라 클래스 설계자가 할 수 있습니다.
class GoodClass
{
private:
int pri_prime_number;
public:
// 편의를 위해 내부에 선언합니다
int getPrimeNum()const
{
// 읽기전용으로 액세스 할 수 있습니다
return pri_prime_number;
}
void setPrimeNum(int arg_number)
{
// 대입이 이루어지기 전에 사전 오류 처리 혹은 예외처리를 클래스 차원에서 할 수 있습니다.
if ( 소수인지 아닌지 검사를 하고 소수일때만 대입 )
pri_prime_number = arg_number;
}
};
GoodClass라는 이름을 붙이고 작성하였지만 오류에 대한 처리를 완벽하게 하지는 않고 있습니다^^;;
그러나 private으로 선언했을때와 public으로 선언했을때의 차이를 명확히 이해하는데는 충분하지 않나 생각합니다.
작성하시는 트리 같은 자료구조에서는 메모리 연산이 많이 이루어질터 getter/setter를 거치느냐 거치지 않느냐의 차이는 큽니다.
예를들면 public으로 선언되었을 때 루트의 왼쪽 자식의 원소값을 읽어오기위해 다음과 같이 접근한다고 가정할때
leftNode가 만약 NULL이나 유효하지 않은 메모리 주소값을 가지고 있다면 다음과 같은 접근은 런타임에서 오류가 발생합니다
tree.leftNode.element // runtime error
그러나 getter를 미리 만들어둔다면
읽어올 값을 리턴하기전에 미리 NULL인지 아닌지를 검사 한 후 런타임 오류를 방지 할 수 있습니다.
물론 이러한 문제는 getter를 사용하지 않고 클래스 사용자 입장에서 처리 할 수도 있겠습니다만,
우리가 어떠한 물건을 구입 할 때, 고장 나지 않고 견고한 제품이 환영받는 것처럼
클래스 또한 설계자가 얼마나 견고하게 만드느냐가 중요하기에 이러한 문제를 사용자에게 돌리기보다는
클래스 설계자가 구현을 하고 사용자는 편하게 사용만 한다는 것입니다. 이것이 객체지향의 철학이기도 하구요..
장황하게 글이 길어졌습니다.. 그럼 즐프하시길^^
댓글 달기