在 ostream 中使用 operator const char*
Using operator const char* in ostream
我正在尝试重载运算符 <<
,以便可以使用 cout
打印错误。我需要打印 m_messag
e 指向的 c-string
。谁能帮我解决这个问题?
My Error.h
header :
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 ;
}
当我执行它时,它给出了正确的输出,但它因以下错误而崩溃:
Exception thrown: read access violation.
_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));
}
我将你的所有代码复制到一个文件中以找出问题所在。缺少 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
嗯。那么,你描述的问题在哪里?我不喜欢这种设计(品味问题),但它按预期工作。我寻找潜在的泄漏或错误:
如果用 nullptr
调用 Error::message()
,那么 strlen()
(和 strcpy()
)可能会崩溃。如果你用 "Do not call Error::message()
with a nullptr
." 之类的东西记录 API 我会觉得这就足够了。
您没有提供所有信息,或者您没有在调试器中测试这个示例。
您真正需要了解的是调试器的工作原理:
单击文本编辑器左侧的灰色栏可放置一个断点。在调试模式下,执行将在断点处(自动)停止。相应的源代码可见(抬起编辑器选项卡并适当滚动文本。
F9 ... 在当前行切换断点
F10 ...单步执行(单步 - 将函数作为一条语句执行)
F11 ...单步执行(单步-进入函数)
Shift F11 ... 跳出(从当前函数执行代码直到 return)
F5 ... 执行代码(一直到断点)
所有这些命令都可以在菜单栏和工具栏上使用。不过记住上面的键,调试起来更方便
此外,熟悉 Local, Watch, and Call Stack。
我正在尝试重载运算符 <<
,以便可以使用 cout
打印错误。我需要打印 m_messag
e 指向的 c-string
。谁能帮我解决这个问题?
My Error.h
header :
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 ;
}
当我执行它时,它给出了正确的输出,但它因以下错误而崩溃:
Exception thrown: read access violation.
_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));
}
我将你的所有代码复制到一个文件中以找出问题所在。缺少 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
嗯。那么,你描述的问题在哪里?我不喜欢这种设计(品味问题),但它按预期工作。我寻找潜在的泄漏或错误:
如果用 nullptr
调用 Error::message()
,那么 strlen()
(和 strcpy()
)可能会崩溃。如果你用 "Do not call Error::message()
with a nullptr
." 之类的东西记录 API 我会觉得这就足够了。
您没有提供所有信息,或者您没有在调试器中测试这个示例。
您真正需要了解的是调试器的工作原理:
单击文本编辑器左侧的灰色栏可放置一个断点。在调试模式下,执行将在断点处(自动)停止。相应的源代码可见(抬起编辑器选项卡并适当滚动文本。
F9 ... 在当前行切换断点
F10 ...单步执行(单步 - 将函数作为一条语句执行)
F11 ...单步执行(单步-进入函数)
Shift F11 ... 跳出(从当前函数执行代码直到 return)
F5 ... 执行代码(一直到断点)
所有这些命令都可以在菜单栏和工具栏上使用。不过记住上面的键,调试起来更方便
此外,熟悉 Local, Watch, and Call Stack。