2017-03-16 1 views
0

cout을 사용하여 오류를 인쇄 할 수 있도록 << 연산자를 오버로드하려고합니다. m_messag을 가리키는 c-string을 인쇄해야합니다. e. 누구든지이 문제를 해결할 수 있습니까?ostream에서 연산자 const char * 사용

My Error.h 헤더 : 내가 그것을 실행하면

ifndef ICT_ERROR_H_ 
#define ICT_ERROR_H_ 

#include <iostream> 
namespace ict { 
    class Error { 
     char* m_message; 
    public: 
    // constructors 
     Error(); 
     Error(const char* errorMessage); 
    // destructor 
     virtual ~Error(); 
    // deleted constructor and operator= 
     Error(const Error& em) = delete; 
     Error& operator=(const Error& em) = delete; 
    // operator= for c-style strings 
     void operator=(const char* errorMessage); 
    // methods 
     void clear(); 
     bool isClear()const; 
     void message(const char* value); 
    // cast overloads 
     operator const char*() const; 
     operator bool()const; 
    }; 
    // operator << overload prototype for cout 
    std::ostream& operator<<(std::ostream& os, const Error& E); 
} 
#endif 

Error.cpp 

#define _CRT_SECURE_NO_WARNINGS 
#include <cstring> 
#include "Error.h" 

namespace ict{ 
    Error::Error() 
    { 
     m_message = nullptr; 
    } 
    Error::Error(const char * errorMessage) 
    { 
     m_message = nullptr; 
     message(errorMessage); 

    } 
    Error::~Error() 
    { 
     delete[] m_message; 
    } 
    void Error::operator=(const char * errorMessage) 
    { 
     clear(); 
     message(errorMessage); 
    } 
    void Error::clear() 
    { 
     delete[] m_message; 
     m_message = nullptr; 
    } 
    bool Error::isClear() const 
    { 
     bool status = false; 
     if (m_message==nullptr) { 
      status = true; 
     } 
     return status; 
    } 
    void Error::message(const char * value) 
    { 
     delete[] m_message; 
     m_message = new char[strlen(value)+1]; 
     strcpy(m_message,value); 
    } 
    Error::operator const char*() const 
    { 

     return m_message; 
    } 
    Error::operator bool() const 
    { 
     return isClear(); 
    } 
    ***std::ostream& operator<<(std::ostream& os, const Error& E) { 
     if (E.isClear()) { 

     } 
     return os << E.operator const char *(); 

    }*** 
} 

Main.cpp 

int main(){ 
    Error T("Testing Error Message"); 
    cout << T << endl ; 

} 

, 올바른 출력을 제공하지만 다음과 같은 오류와 충돌 : 던져

예외 : 액세스 위반을 참조하십시오.

_First는 nullptr입니다.

디버거 :

static size_t __CLRCALL_OR_CDECL length(const _Elem *_First) 
      { // find length of null-terminated string 
    //next statement to be executed ---> return (*_First == 0 ? 0 
       : _CSTD strlen(_First)); 
      } 
+0

그리고 디버거를 사용하여 코드를 단계별로 실행할 때 디버거에서 예외가 발생했다고 주장하는 행은 무엇입니까? –

+0

@SamVarshavchik 죄송합니다, Visual C++ 디버거에 익숙하지 않지만 Error.cpp 파일의 특정 줄 대신 위의 디버거 코드를 가리키는 것 같습니다 – elvisi27

+0

@SamVarshavchik 문제는 57 번 줄에 있다고 생각합니다. : return os << E.operator const char *() main.cpp의 17 행에 eprinted 될 때 : cout << T << endl; – elvisi27

답변

0

내가 뭐가 잘못 알아 하나 개의 파일에 모든 코드를 복사됩니다. operator <<()의 테스트 (오류가 확실한 지 여부)가 누락되었습니다. 그러나 테스트에서이 지점은 활성화되지 않아야합니다.

#include <iostream> 
#include <cstring> 
#define _CRT_SECURE_NO_WARNINGS 

namespace ict { 
    class Error { 
     char* m_message; 
    public: 
    // constructors 
     Error(); 
     Error(const char* errorMessage); 
    // destructor 
     virtual ~Error(); 
    // deleted constructor and operator= 
     Error(const Error& em) = delete; 
     Error& operator=(const Error& em) = delete; 
    // operator= for c-style strings 
     void operator=(const char* errorMessage); 
    // methods 
     void clear(); 
     bool isClear()const; 
     void message(const char* value); 
    // cast overloads 
     operator const char*() const; 
     operator bool()const; 
    }; 
    // operator << overload prototype for cout 
    std::ostream& operator<<(std::ostream& os, const Error& E); 
} // namespace ict 


namespace ict{ 
    Error::Error() 
    { 
     m_message = nullptr; 
    } 
    Error::Error(const char * errorMessage) 
    { 
     m_message = nullptr; 
     message(errorMessage); 

    } 
    Error::~Error() 
    { 
     delete[] m_message; 
    } 
    void Error::operator=(const char * errorMessage) 
    { 
     clear(); 
     message(errorMessage); 
    } 
    void Error::clear() 
    { 
     delete[] m_message; 
     m_message = nullptr; 
    } 
    bool Error::isClear() const 
    { 
     bool status = false; 
     if (m_message==nullptr) { 
      status = true; 
     } 
     return status; 
    } 
    void Error::message(const char * value) 
    { 
     delete[] m_message; 
     m_message = new char[strlen(value)+1]; 
     strcpy(m_message,value); 
    } 
    Error::operator const char*() const 
    { 

     return m_message; 
    } 
    Error::operator bool() const 
    { 
     return isClear(); 
    } 
    std::ostream& operator<<(std::ostream& os, const Error& E) { 
     if (E.isClear()) return os; 
     return os << E.operator const char *(); 
    } 
} // namespace ict 

int main(){ 
    ict::Error T("Testing Error Message"); 
    std::cout << T << std::endl; 
    return 0; 
} 

Windows 10 (64 비트)에서 VS2013으로 컴파일하고 디버거를 시작했습니다.

제가 알기로, return 0;main()에 넣었습니다. 사실, 그것을 버릴 수는 있지만 중단 점을 배치하는 것이 좋습니다. 따라서 다음 출력을 얻었습니다.

Testing Error Message 

Hmm. 그럼, 당신이 묘사 한 문제는 어디에 있습니까? 나는 디자인 (맛의 문제)을 좋아하지 않지만 예상대로 작동합니다. Error::message() 아마 충돌하는 nullptr 다음 strlen() (및 strcpy())로 호출

경우 : I 잠재적 누출 또는 버그 보았다. "Error::message()nullptr으로 전화하지 마십시오."와 같은 API를 문서화하는 경우 나는 이것으로 충분할 것입니다.

모든 정보를 제공하지 않았거나 디버거에서 샘플을 테스트하지 않았습니다. 당신이 정말 알아야 할

는 디버거가 작동하는 방법이다 : 텍스트 편집기 (들)의 왼쪽에있는 회색 바의

  • 클릭하면 중단 점을 배치합니다. 디버그 모드에서 실행은 중단 점에서 (자동으로) 중지됩니다. 각각의 소스 코드는 편집기 탭을 발생시키고 적절히 스크롤링 텍스트 (표시된다.

  • F9 ...

  • F10는 ... 위에 단계 전류 선에 전환 브레이크 포인트 (단일 1 단계로 함수를 실행)

  • F11 ...의 단계 (단일 단계 - 기능 입력)

  • 시프트 ... F11까지 연속적으로 (단계 밖으로

  • F5 (현재 함수에서 복귀 할 때까지의 코드를 실행 ...) 코드를 실행할 중단 점)

이러한 모든 명령은 메뉴 모음과 도구 모음에서 사용할 수 있습니다. 그러나 디버깅은 위의 키를 기억하는 것이 더 편리합니다.

또한 Local, Watch, and Call Stack에 익숙해집니다.

+0

"return os;를 추가하는 것만으로도 작업이 필요한 것 같습니다." after if (E.isclear()). 디버거에 도움을 주셔서 감사합니다. – elvisi27

관련 문제