트리 노드 클래스의 좌트리 우트리 멤버 변수에 대한 질문입니다.

allsoft의 이미지

보통 클래스 멤버 변수들은 private로 선언합니다.
get set을 이용해서 접근하지요..

left_node와 right_node는 멤버 변수이지만 public으로 선언해도 상관없는지요?
아니면 이것도 역시 private로 선언해서 get set로 접근해야 하는지.. 답변 좀 부탁드릴게요

rareboy의 이미지

private, public 같은 접근 지정자를 설정하는 것은
개발자 마음입니다.
일반적으로 객체지향 언어들에서는 모든 필드(즉, 멤버변수)는 private으로 선언하고 get/set 함수를 만들어 접근하는 것을 원칙으로 합니다
left_node와 right_node는 일반적으로 position의 개념을 포함하므로 흔히 링크드 리스트와 같이 메모리 연결 방식을 사용한다고 가정하면 메모리와 관련된 오류가 발생할 확률이 높습니다. 그러므로 public으로 선언해두게 되면 안정성 검사를 하지 않고 바로 접근할 수 있으므로 위험한 코딩이 될 가능성이 높습니다. 그러므로 private로 선언 후 public 접근을 하는 편이 좋다고 생각합니다. 물론 이건 제 생각이고 또 많은 경우 그렇게 한다는 것이지 필수 불가결의 선택은 아닙니다.

allsoft의 이미지

==================
불가능은 없다. (Nothing is Impossible,, Possible)

==================
불가능은 없다. (Nothing is Impossible,, Possible)

d3m3vilurr의 이미지

getter/setter를 쓰면 외부에서 변경 통로가 하나로 정해진다는 점에서 좋은 점이 생깁니다.
그건 바로 타겟 변수가 바뀌더라도 그것과 getter/setter부분만 고쳐주면 된다는 점입니다.
물론 메서드명 자체가 바뀌면 동일한 수준의 변경이 필요하지만요.

사실 getter/setter를 안썼을때 변수가 외부에서 바뀌는 경우가 생긴다는 지적은 조금 다른 문제가 아닌가 싶습니다.
setter가 protected나 private가 아닌 public으로 존재할 때(즉, 외부에서 접근이 가능할 때), 이 변수의 값은 언제든지 변경될 위험이 따르기 때문이죠.

rareboy의 이미지

윗분의 답변을 읽어보니 제가 문장력이 짧아서 오해가 있으셨던 것 같습니다.
질문자님께서 제 말뜻을 잘못 이해하셨을까봐 조금 더 보충하여 답변을 올립니다.

제가 전달하고자 했던 외부에서의 갱신을 안정적이라는 말의 뜻은
변수로의 직접적인 할당보다 안정적인 방법을 취할 수 있다는 것입니다.
예를들어 아래와 같은 클래스가 있다면
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를 사용하지 않고 클래스 사용자 입장에서 처리 할 수도 있겠습니다만,
우리가 어떠한 물건을 구입 할 때, 고장 나지 않고 견고한 제품이 환영받는 것처럼
클래스 또한 설계자가 얼마나 견고하게 만드느냐가 중요하기에 이러한 문제를 사용자에게 돌리기보다는
클래스 설계자가 구현을 하고 사용자는 편하게 사용만 한다는 것입니다. 이것이 객체지향의 철학이기도 하구요..

장황하게 글이 길어졌습니다.. 그럼 즐프하시길^^

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.