C++ 에서 forward declaration 문제

땡찬의 이미지

missu@ubuntu:~/src/tc++pl/string/test$ cat string.cpp
class String {
         struct Srep;
         Srep *rep;

         class Cref;
public:
         class Range{};
         void check(int i) const { if ( i< 0 || rep->sz <= i) throw Range(); }

};


struct String::Srep {
         char *s;
         int sz;
         int n;

};

class String::Cref {
         friend class String;
         String &s;
         int i;
};

missu@ubuntu:~/src/tc++pl/string/test$ make string
g++    -c -o string.o string.cpp
string.cpp: In member function ‘void String::check(int) const’:
string.cpp:8: error: invalid use of undefined type ‘struct String::Srep’
string.cpp:2: error: forward declaration of ‘struct String::Srep’
make: *** [string.o] 오류 1
missu@ubuntu:~/src/tc++pl/string/test$

The C++ Programming Language 를 공부하면서 책에 있는 소스를 손에 익힐겸 치면서 공부하고 있습니다. 뭔가 간단하게 해결될 것 같은데...저는 도저히 답이 안나옵니다. 벌써 400페이지 정도 까지 왔는데..이 것도 하나 해결못하니 한심한 생각이 드는군요.

참고로 check() 함수를 주석처리 해주면 문제없이 컴파일이 됩니다. class Sref; 의 선언가지고는 class Sref 안에있는 char *s 를 알 수 없다고 투덜거리는 것 같은데..도대체 어떻게 해결해야 하는지 모르겠습니다. 등이 몹시 가렵습니다. 좀 시원하게 긁어주세요~

익명 사용자의 이미지

휴.. 헤더파일이 괜히 있는게 아니죠...

IDNed의 이미지

Effective C++에서 본 내용과 비슷하네요 ^^

일단 전방선언해서 Srep *rep;까지는 맞습니다.
(참고로 하나 말씀드리면 Srep rep;은 안됩니다. *rep이나 &rep같은 포인터/레퍼런스만 가능합니다. 까닭은 구조를 모르므로 클래스 객체의 크기 결정을 못하기 때문이구요..)

문제는 check 함수에 있습니다.
rep->sz 참조부분에서 에러가 날텐데, 구조를 모르므로 sz를 참조하는게 말이 안되는거죠...
sz타입이 뭔지에 따라 기계어가 달라질텐데 당연합니다.

방법은 struct 정의를 check 앞에 해주어야 합니다. 선언이 아니라...
아니면 check 함수의 정의부(선언부는 inline 앞에 붙이면 되겠죠 ^^)를 struct 정의 뒤로 따로 빼주면 되겠죠..

땡찬의 이미지

아 그렇군요. 책에 있는대로 믿고(?) 쳐 봤는데. 비얀 아저씨가 책 쓰기 귀찮아서 그냥 class { ... } 안에 집어넣어버린 모양이군요. 친절한 답변 감사드립니다. 다시 진도 나갈 수 있겠습니다.

all my trouble's gone

댓글 달기

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