구조체를 감싸고 있는 구조체를 클래스화 할때..

hwandori의 이미지

typedef struct _A {
  int a1;
  int a2;
} A;
typedef struct _B {
  int b1;
  int b2;
} B;

typedef struct _X {
  A Xa;
  B Xb;
} X;

이때 A , B , X를 클래스화 한다면 주로 어떤방식을 사용하는지 궁금합니다.

지금 A , B를 클래스화 할때 a1 ,a2 , b1 , b2 에 대한 get , set메소드를

구현하고 X에서 다중상속으로 A , B를 상속받는 형식으로 되어있는 소스를

보았습니다. 얼른 좋지 않게 보이는데, 그냥 단순히

class X {
private :
A Xa;
B Xb;
public :
....// get , set...
};

이런게 나은지도 알고 싶고...

어떠한 방식이 좀더 정석적이며 나중에 확장하기에 용이한지 알고 싶습니다....

yielding의 이미지

그리 고민할 문제가 아닌것 같군요..

private, protected는 구현상속이지요 그래서

class X: private A,  private B {
};

라이브러리 프로그래머라면 이렇게 구현할 일이 많이 있을것이지만 (empty base class optimization의 이득이 있지요)

struct X {
  A Xa;
  B Xb;
};

하지만 이 자체로도 충분히 깔끔한것 같습니다.

기우로 말씀을 드리자면, C++로 프로그램할때 반드시 클래스를 써야한다든지, 가능한 상속을 해야한다 하는 강박관념을 가지기 쉬운데
우선은 문제를 이루고 있는 핵심적인 부분들을 잘 모델링해서 클래스를 만들고 관계를 설정한다면, 나머지 부분들은 좀 편하게 생각하면서 간단하게 구현하는게 좋을 듯 합니다.

Life rushes on, we are distracted

ssehoony의 이미지

저 같은 경우 다음과 같은 규칙을 세웠습니다.

Quote:
오버로딩이 필요하거나 가상함수를 이용해야 하거나 프로텍트 함수나 변수를 접근해야 할경우, 다형성(폴리모피즘)이 필요한 겨우에는 상속을 받지만, 그렇지 않을 경우는 그냥 멤버 변수로 만들어서 사용한다.

코딩이라는게 이게 효율적이다 라는건 있지만 정답이라는게 없기 때문에 자기 나름의 소신을 갖고 설계를 하면 되는 거겠지만

어떤 경우에는 상속을 하고, 어떤 경우에는 멤버변수로 만들어서 사용하는 걸까? 라는 고민을 했었는데 내린 결론은 위에 와 같습니다.

오버로딩, 가상함수, 다형성, 프로텍트 함수/변수를 접근하지 않는 이상 상속 받을 이유가 없으며, 별 이유없이 상속 받으면 나중에 유지/보수를 위해 소스를 다시 분석할 때도 상속 부분 때문에 더 신경을 써여하게되고 부모 클래스의 함수/변수 스코프도 생각을 해야 해서 상속을 사용하지 않을 수 있다면 최대한 하지 않는다. 라고 나름의 규칙을 세웠습니다.

아직은 경력과 지식이 많이 않으므로 위의 소신이 변경되는 날이 올 수도 있겠지만 현재까지는 위의 규칙에 따라 구조를 잡습니다.

( UML 을 이용해 클래스를 설계하시나요? 상속이나 연결/의존 관계를 깔끔하게 설계할 수 있어 좋더군요 )

doldori의 이미지

yielding 님의 견해에 동감합니다. 아마 C에서 쓰던 구조체를 클래스로
바꾸시려는 것 같은데, C의 구조체는 데이터의 단순한 집합체일 뿐이며
어떤 개념을 나타내는 클래스와는 성격이 매우 다릅니다. 전체적인 관점에서
A, B, X간의 관계를 설정하지 않고 단순히 클래스 형태로 바꾼다고 해서
얻는 이득은 별로 없을 것입니다.

yielding wrote:
라이브러리 프로그래머라면 이렇게 구현할 일이 많이 있을것이지만
(empty base class optimization의 이득이 있지요)

empty base class optimization이 어떤 것인지 설명해 주시면 고맙겠습니다.

yielding의 이미지

class Empty {  --------- (1)
};

class Empty2: public Empty { ------- (2)
};

class Empty3: public Empty2 { -------(3)
};

template<typename T1, typename T2>
class X: public T1, public T2 {             ---------- (4)
};

template<typename T1, typename T2>
class X {             ---------- (5)
public:
   T1 t1;
   T2 t2;
};

(1)의 경우 sizeof(Empty)가 1입니다. 멤머가 하나도 없다고 size 가 0일 순 없겠죠(그럴경우 Empty arr[100]의 사이즈가 0인 이상한 경우가 발생하겠죠)
sizeof(Empty2), sizeof (Empty3)의 경우도 1입니다. (alignment를 고려해서 size가 4인 컴파일러도 있겠죠, g++은 1이네요)

이렇게 (2), (3)의 경우 역시 sizeof의 결과가 1이나오는 것이 empty base class optimization(EBCO)입니다. (C++ standard does specify that when an empty class is used as a base class, no space needs to be allocated for it provided that it does not cause it to be allocated to the same address as another object or subobject of the same type, C++ Templates the complete guide 참조)

그런데 실전에서 (1) ~ (3)처럼 코딩할 일은 없죠.. (4)의 경우는 많습니다..
T1, T2가 구조체, 엄청 큰 클래스 혹은 Empty클래스 어떤 것이 들어더라고 동작하도록 generic하게 클래스를 설계해서 쓸일이 많습니다.
ATL도 그렇고 Loki, boost도 ... generic programming library에서는
이렇게 구현하는 일이 많습니다. (실전보다는 라이브러리군요. 그래서 이전 댓글에서 라이브러리 프로그래머가 많이 쓴다고 했습니다.)

(5)나 (4)의 차이는 거의 없으나 (4)는 EBCO가 지원이되고 그다음 T1, T2의 public interface가 X의 public클래스로 노출되는 장점이 있습니다. (The modern C++ design 참조)

또 여담으로, 저도 실은 C++에 강한 애착이 있는 편이라서 완벽한 코딩 원칙을 가질려고 많은 노력을 했습니다. 하지만 이렇게 생각하고 공부하는게 끝도 없는데 반해서 실제 프로젝의 일정은 끝이 딱 정해져있죠. 그래서 자칫 생각을 잘못하면 생산성 없는 프로그래머로 낙인찍히기 좋겠다는 생각이 들었습니다.
숲을 잘 보고 나무를 봐야겠습니다.

Life rushes on, we are distracted

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.