2017-03-16 147 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 was 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行:當它在main.cpp的第17行上被打印時,返回os << E.operator const char *():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編譯它並啓動了調試器。

如您所見,我在main()中加入了return 0;。實際上,它可以放棄它,但放置一個斷點是一個好的方面。因此,我得到了以下輸出:

Testing Error Message 

嗯。那麼,你描述的問題在哪裏?我不喜歡這個設計(關於品味),但它按預期工作。我尋找潛在的泄漏或錯誤:

如果Error::message()被稱爲nullptr然後strlen()(和strcpy())可能會崩潰。如果您用類似「不要撥Error::message()nullptr」的文檔記錄API。我會發現這是足夠的。

要麼你沒有提供所有信息,要麼你沒有在你的調試器中測試這個樣本。

你真正需要知道的是,你的調試器是如何工作的:

  • 單擊左文本編輯器(S)的灰色欄放置一個破發點。在調試模式下,執行將在斷點停止(自動)。相應的源代碼可見(提高了編輯器選項卡,並適當地滾動文本。

  • F9 ...在當前行切換斷點

  • F10 ...步過(單步驟 - 執行功能作爲一個聲明)

  • F11 ...在步(單步 - 輸入功能)

  • F11 ...跳出(執行代碼,直到從當前函數返回)

  • F5 ...執行代碼(連續直到斷點)

所有這些命令在菜單欄和工具欄上可用。但是,調試更方便記住上述密鑰。

另外,熟悉Local, Watch, and Call Stack

+0

它似乎只需添加「return os」即可工作。 if(E.isclear())後。也非常感謝您對調試器的幫助。 – elvisi27

相關問題