2017-03-16 146 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

相关问题