기초적인 C++문법을 물어봅니다 -_-;;

ixevexi의 이미지

하.. 자꾸 이런 질문을 하는제가 부끄러워지는군요 ㅠ.ㅜ
제가 하는 질문들은 다 기초적인것들이라서 ...

근데 제가 가진 책들엔 나와있지않아서 용기를 내어 올려봅니다.
지금 exception을 써서 프로그래밍을 할까 하는데
어디선가 exception class에 정보를 주더라구요!

class x{
    ...

    class exception{};

    ...

};


보통은 저런식으로 의미없는 더미?클래스를 쓰지만

class x{

    ...

    class detailed_exception
    {
    public:
       static char error_log[80];
    };

    ...
}

이렇게하면 catch구문에서 error_log를 볼 수 있게!! 코딩을
한게 어렴풋이 기억이 납니다.

이제 제 질문은 시작입니다 ^^

과연 저 코드로써 error_log에 문자열을 카피하고
throw detailed_exception; 해서 catch문에서 error_log를 읽을 수
있을까요?

또한 꼭 static코드여야지만 저건 가능한것입니까?
또한 꼭 static이여야지만 가능하다면 함수객체를 만들어 throw할 수는
없는지요 ex) detailed_exception de; throw de;

두번째로 //사실 이게 진짜 궁금했습니다.//
저것이 된다면 상세한 detailed_exception을 작성하려고 합니다.
그런데 클래스 안에다 써넣기 참 거시기하네요 ^^

그래서 class안에다가는 선언! 만 하고
정의는 class 밖에다 할 수 있을까요? 만약 할 수 있따면 예제를 들어
어떻게 해야할지 가르침을 주시기 바랍니다.

juicy의 이미지

부끄러워할만한 질문은 아니네요..
꽤 괜찮은 질문입니다. 도전적이예요..
(그래도 여기 kldp bbs는 수준이 좀 괜찮아서..
'c로 국어,수학 평균 계산하는 프로그램' 같은 생초보같은 질문은 없는 것 같네요..ㅋㅋ)

저도 c++에 많은 관심을 가지고 있어서,
(현재 c++ 파서 제작중... 거의 완성...)
좀 찾아보면서 자세히 답변을 드리고 싶은데,
지금 시간이 보시다시피...-_-(졸려서..)

두번째 질문에는 지금 대략 답변 드릴 수 있겠네요.

<내부 클래스 멤버 함수 정의(definition of inner class member function)>

클래스 선언은 이렇게 하고...

class A
{
   class IN_A { void IN_A_member(); };
};

멤버 함수 정의는 아래처럼 하면 됩니다.

void A::IN_A::IN_A_member()
{
}

inner class가 anonymous(익명)이면 이렇게 쓰지는 못할 겁니다.

ps. 나중에 시간되면 첫번째 질문도 살펴보죠..^^

ixevexi의 이미지

두번째 질문에 대한 답변감사드립니다.

그런데 제가 질문을 모호하게 한것 같군요

전 클래스 안에 정의한 클래스의 메쏘드를 밖에다 정의하는걸 원하는게 아니라
클래스 안에 선언만 해둔 클래스 그 자체를 밖에서 정의할 수 없는지
물은것이었습니다.

class outer{

    ...
    class inner;
    ...
}

//그리고 여기다가 class inner의 메쏘드의 선언과 정의를 동시에...

C++, 그리고 C++....
죽어도 C++

yielding의 이미지

최고의 c++ reference는 ISO/IEC 14882:1998문서입니다.
조만간 14882:2003이 서점에 나올겁니다. (Wiley에 보면 있음)

14882:1998은 당나귀한테 물어보시면 됩니다.

9.7.3

If class X is defined in an namespace scope, a netes class Y map be declared in class X and later defined in the definition of class X or be later defined in a namespace scopde enclosing the definition

ex)

class E {
   class I1;
   class I2;
   class I1 {};
};
class E::I2 {};

됬지요 ? ^^;

그리고 static char error_log[80]; 요렇게 써야만 하는 이유 보다
1. exception message를 동적할당하지 않는 이유: 동적할당시 exception 발생가능
2. local array 쓰지 않는 이유 : 마땅히 안쓰는 이유는 없어보이지만 array size가 너무클 경우 stack overflow를 생각한게 아닐까 (80정도면 뭐 큰 사이즈가 아니니까 실제로 넉넉한 컴에서 쓰기엔 문제가 없을듯.)

여하튼 static message[xx] 위와같이 코딩한 근본적인 이유는 static 변수는 할당이 컴파일타임에 (BSS인가?) 한 번만 이루어지므로 exception도중 또 exception이 일어나지 않을거라고 생각한듯합니다. (이 추측은 좀 거시기 합니다.)

마지막으로 ZThread의 Exception 클래스의 base 클래스를 함 살펴보면
1. 굳이 inner class 사용하지 않고, 2. 사용자가 실수로 동적할당하는 것을 막기위해 new operator를 private에 선언합니다. (아시죠 이렇게 하는거?)

class Synchronization_Exception {

  // Restrict heap allocation
  static void * operator new(size_t size);
  static void * operator new[](size_t size);

  std::string _msg;
  
public:
  
  /**
   * Create a new exception with a default error message 'Synchronization 
   * Exception'
   */
  Synchronization_Exception() : _msg("Synchronization exception") { }

  /**
   * Create a new exception with a given error message
   *
   * @param const char* - error message
   */
  Synchronization_Exception(const char* msg) : _msg(msg) { }

  /**
   * Get additional info about the exception
   *
   * @return const char* for the error message
   */
  const char* what() const {
    return _msg.c_str();
  }
  
}

Life rushes on, we are distracted

ixevexi의 이미지

제 내공이 낮아서 그런지 여전히 의문이 드네요 ^^

두번째에 대한 답변은 확실히 알았습니다.
그리고 첫번째 질문도 일단 가능은 하다라고 알고 있겠습니다.

그런데 exception message를 동적할당하지 않는 이유가
동적할당시 (메모리 부족등을 이유로) 새로운 exception을 낼 수 있기때문에
쓰지 않는다고 설명해주셨는데요.
의문이 드는건

Quote:

std::string _msg;

위의 코드에서도 분명히 string클래스를 예외 클래스내에서 사용하고있습니다.
또한 이 임시클래스가 만들어질때 string값에 어떠한 문자열이 들어갈 것이구요
그렇다면, 제가 알고있기론 string 클래스는 내부에 c_str 포인터가 들어가있고
하는 일을 간략히 살펴보면 c_str의 길이를 보고 그만큼 동적으로 할당해서
내부적으로 포인팅하는 걸로 알고있습니다.
그렇다면 실제로 아무리 new []오퍼레이터나 new오퍼레이터를 사용자가
쓰게 막아도 코드내부에서 힙에 접근하고 있는데 의미가 있나요?

자 또 이제 부터 그럼 질문의 시작입니다.
실제로 제가 왜 이걸 시도하려고 하면요
사용자의 input stream에서 한라인씩 읽어들여서
파싱하다가 잘못된 문자열일 경우 그 읽어드린 한라인을
예외 클래스에 집어넣고 throw 할 것 예정이었습니다.

 ........
try{
    cin>> buffur;
    if( !expected_str(buffur) )
        throw exception( buffur);
}

catch( exception)
{
    //잘못된 구문 -사실 제가 만드려는 프로그램에서는 잘못된것이 아니라 -_-
    //  특수한 경우, 머 관리모드같은걸 여기서 띄우려구요 을 해결한다.
}

그렇다면 여기에 여러가지 후보가 있습니다.

1.

class A{
    private:
        static char error_log[80];
    public:
        A( char * str){
         strcpy( error_log, str);
        }
}

       

2.
class A{
    public:
        char * error_log;
}
try{
     A a;
     a.error_log = new char[80];
     strcpy( error_log, buffur);
     throw a;
}
catch( A &e)
{
   //e에 대한 처리..
}



3.
class A{
 public:
    string error_log;
    A(char * str) :error_log(str){}
}

try{
    ...
    throw A("I don't Know");
}
catch( A)
{
    //처리를 한다.
}



실제론 코드가 3가지 밖에 없지만 제가 묻고 싶은건 거진 다 들어간거 같네요
1번에서는 권장?하신 static후보 -> 이건 확실히 동작하겠죠?
2번에서는 껄꺼름한 static대신에 동적으로 할당해서 클래스가 아닌 객체!를
던지는 방법... 그리고 받을떄도 클래스 자체를 받는게 아닌 -_- 레퍼런스로 받는
방법.. stroustrup의 책을 볼때 저런식으로 캐치가 가능하더라구요.
저게 과연 그냥 class캐치하는 것과 무슨 상관이 있는지요?
제가 알기론 throw할때 임시객체가 생성되어 넘어가지 않나요?
3번은 제가 가장 원하는 방법 ^^
간단히 string 클래스를 쓰고 처리를 할것인데 문제는 catch의 구문에서
도대체 a라는 객체에 접근할 방법을 모르는 거죠
이때 catch( A &e) 라고 명시적으로 e를 만들어 써줘야하나요?

예외처리에 대해선 전혀 모르는 -_- 왕 초보였습니다.

C++, 그리고 C++....
죽어도 C++

akbar의 이미지

ixevexi wrote:
간단히 string 클래스를 쓰고 처리를 할것인데 문제는 catch의 구문에서
도대체 a라는 객체에 접근할 방법을 모르는 거죠
이때 catch( A &e) 라고 명시적으로 e를 만들어 써줘야하나요?

예외처리에 대해선 전혀 모르는 -_- 왕 초보였습니다.


catch( A &e) 라고 명시적으로 e를 만들어 써줘도 되고 Class A 포인터를 전역 혹은 정적멤버 변수로 선언해서 사양해도 됩니다.
그리고 더 심각한 문제는
" string 클래스는 내부에 c_str 포인터가 들어가있고
하는 일을 간략히 살펴보면 c_str의 길이를 보고 그만큼 동적으로 할당해서
내부적으로 포인팅하는 걸로 알고있습니다. "
라고 하셨는데 현재의 string 클래스 구현은 대개 참조카운팅을 합니다.
string a="C++ World";
string b(a);
string c(a);
에서 객체 a,b,c 는 문자열 메모리를 공유합니다.
참고해서 생각하세요
ixevexi의 이미지

답변 감사드립니다. ^^

참조카운팅의 이야기를 읽었었는데 까먹고 있었습니다.
아직 제 몸에 스며들지 않은 탓이겠죠

아마 그 참조카운팅은 string의 원소를 변경하지 않는한 유지가 되겠죠?
그렇다면 과연 예외 클래스안에 있는 string 클래스는
참조카운팅이 유지되는걸 전제로 들어있는건가요?

제가 생각할땐 위태위태하네요 ....

C++, 그리고 C++....
죽어도 C++

yielding의 이미지

흠.. 절 열심히 공부시키시는군요 이른 아침부터 ^^;

0. 14882에서 std::string을 반드시 reference counting을 써서 구현해야한다고 규정하고 있지 않습니다. 많은 stl 중 reference counting을 안하거나 interface는 만들어 놓고 실제는 안쓰고 있는걸로 알고있습니다.

1.

  std::string msg;

말씀하신데로 basic_string도 내부적으로 동적할당을 하겠죠. 힙에 데이타가 할당되는게 문제가 아니라 exception safty를 어떻게 유지하는가가 중요합니다.
하지만 stl은 정말 제대로 설계된 라이브러리입니다. stroustrup의
TC++PL 3rd edition의 부록에 보면 exception safty에 대한 이야기가
나옵니다.. std::string은 basic exception safe입니다.. 이외에
strong, no thorw exception safty가 있는데..

E.2 [3a] ‘‘Basic guarantee for all operations:’’ The basic invariants of the standard library are maintained, and no resources, such as memory, are leaked.

std::string의 모든 member function은 basic es(exception safe)
그중 key operation은 strong es

그럼 결국 std::string은 exception 절대 발생하지 않는가? 그렇지는 않지만 나더라도 프로그래머에게 뒷처리를 깔끔하게 할 수 있는 충분한 여지를 준다는 거지요. 처음에 제 대답에도 문자열 사이즈가 적다면 static 동적할당, 배열 등이 큰 문제가 없을거라고 말씀드렸고, ZThread에서 new operator를 private에 선언하는것은 눈여겨 볼만한 코드라는 것입니다.

2. 후보코드 중에서 3에서 catch(A &e) 하시면 됩니다. 임시 객체가 만들어지지만(감으로 때려씀) catch(A e)라고 하면 이 임시객체를 한번더 카피해서 2개의 임시 객체가 만들어지겠죠. reference로 받는것은 추가적인 copy를 피하기 위해서 이죠. catch(A)라고만 하면 exception의 종류만 확인하고 그 exception 객체가 가지고 있는 자세한 정보는 관심 없다는 거겠죠.. (대충 감으로 때려씀)

3. 참고할만한 서적은
1) 14882:1998 ^^;
2) stroustrup아자씨의 TC++PL의 exception chapter, 부록 E
3) Exceptional C++, Sutter
4) Boost에서 열나 활동하고 있는 David Abrahams의 글입니다

4. 마지막으로 제가 정확하게 찾아보지 않고 거시기하게 쓴 대답은 직접 공부하셔서 명쾌하게 좀 올려 주시면 감사하겠습니다.

Life rushes on, we are distracted

ixevexi의 이미지

하아 ^^ 역시 C++는 어렵군요

하지만 그 이상으로 흥미롭습니다.
좋은 답변 감사드리고요, 더 공부해야할것 같습니다.

제가 보는 책은 Teach your self C++로 문법을 봤고
C++전체에 대해선 TC++PL special edition으로 보고있습니다.(지금 한 반 넘게 읽었습니다 ㅠ.ㅜ)
STL은 C++스탠다드라이브러리 레퍼런스라는 책을 보고 있는데

이것만으로는 제가 가지는 의문들을 풀기엔 역부족인듯 합니다. ㅠ.ㅜ
어디 C++고수들이 사는 좋은 커뮤니티 없을까요?

말씀해주신 자료들은 제가 꼭 찾아 보겠습니다 ^_^

PS: 다시 한번 원주제로 돌아가서 조그만 질문을 드리자면

class A{};

...
throw A;
...

라는 구문에서 throw는 A의 임시객체를 catch구문으로 던지는 거겠죠?
그렇다면

A a;
throw a;

이렇게 명시적으로 객체를 던지면 어떻게 될까요? 복사가 일어날까요? ^^

조금더 덧붙이자면 위에서 throw A했을때 A의 임시객체의 살아있는 시간이
명시적으로 자신의 블럭 밖(즉 catch 구문 밖)으로 나와도 스택에 쌓여있는건가요?

아~ 어렵습니다. 저 A의 임시객체는 도대체 정체가 멀까요 ㅠ.ㅜ

C++, 그리고 C++....
죽어도 C++

yielding의 이미지

1. catch에서 A& e라고 하지 안고 catch(A e)라고 하면 temporary를 당근 복사하겠죠.

2. 가장 확실한 답은 적어주신 예제는 간단하게 짜서 A의 생성, 소멸자에 breakpoint를 걸고 trace해보면 눈으로 보면됩니다.

3. C++의 고수들이 사는 커뮤니티는
3.1 bbs.kldp.org ^^;
3.2 뉴스그룹: comp.lang.c++.moderated : 초보부터, david abraham, andrei alexandresu, stroustrup등의 초 울트라 수퍼 고수까지 열라 활동중.. 여기 질문하면 입이 딱벌어지게 답이 올라옵니다...
3.3 www.boost.org

4. ISO 14882를 잠깐 보면

12.2
Temporaries of class type are created in various contexts. binding an rvalue to a reference(8.5.3), returring an rvalue(6.6.3), a conversion that creates an rvalue(4.1, 5.2.9, 5.2.11, 5.4), throwing an exception (15.1), entering a handler(15.3), and in some initializations (8.5) 등등 (아이고 손아파..)

15.1.4 ~ 15.1.5
temporary object의 life time에 대한 답이 있습니다.(손아파 못치겟음)

당나귀한테 물어보세요... 줄겁니다 이 문서.

여담으로, C++의 세세한 문법에 대해서 정확하게 많이 알려고 하는것은 정신 건강이나 프로젝트의 진행에 그리 좋지 않은거 같습니다... 저도 C++에 약간 편집증이 있는편인데 첨부터 잘못 습관을 들인것 같다는 생각이 듭니다..
질문의 내용, 날카로움을 봐서도 결고 C++의 초보가 아니신거 같기도 하고요.. 진정한 C++의 고수라면 전체적으로 잘 디자인하고 세부적으로는 단순하게 프로그램 하겠죠... KISS(Keep It Simple Stupid)가 생각나군요..

하지만 예전에 유명한 아자씨가 "많은 사람들이 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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.