1

我最近在做一些套接字编程并开始用 C++ 编写代码。由于我正在尝试编写的程序将有几个组件必须通过套接字进行通信,所以我决定将套接字通信封装在一个类中。

由于可能会发生几个错误,因此我决定为套接字异常创建一个类,我将其定义如下:

class SocketException: public std::exception {
public:
  SocketException(const std::string &message);
  ~SocketException() throw();
  virtual const char * what() const throw();
private:
  std::string msg;
};

实现如下:

SocketException::SocketException(const std::string &message) : msg(message) {}
SocketException::~SocketException() throw() {}

const char * SocketException::what() const throw() {
  std::stringstream stream;
  stream << msg + " Error number: ";
  stream << WSAGetLastError();
  return stream.str().c_str();
}

到目前为止,该what()方法的实现还不完整,因为我想通过显示错误代码的文本含义,FormatMessage()但我还没有写出来。

我在 Visual Studio 中尝试了这段代码,但没有像我预期的那样工作,该what()方法返回垃圾。在花了很长时间试图找出问题并尝试不同的事情之后,我最终尝试了不同的编译器。

使用 MinGW (GCC) 代码按预期编译和运行,消息显示为我认为的那样(如果有人感兴趣,我只是connect()在未连接到 Internet 时尝试执行)。

我只是在学习 C++,我想知道问题出在哪里,或者什么是合适的方法。

编辑:感谢您的评论和回答,起初我以为是这样,所以我曾经new分配流(即使知道它会泄漏,只是为了尝试new使用堆),结果是同样,这就是我所拥有的:

const char * SocketException::what() const throw() {
  std::stringstream *stream = new std::stringstream();
  *stream << msg + " Error: ";
  *stream << WSAGetLastError();
  return (*stream).str().c_str();
}
4

2 回答 2

1

您正在返回一个指向what函数本地变量的指针,从而为调用者留下一个悬空指针:

const char * SocketException::what() const throw() {
  std::stringstream stream;  // this stringstream will die on exiting this scope
  stream << msg + " Error number: ";
  stream << WSAGetLastError();
  return stream.str().c_str();
}

那是未定义的行为。这意味着任何事情都可能发生。

安全返回的方法的示例const char*是这样的(显然它没有原始的预期功能,仅用于说明目的):

const char * SocketException::what() const throw()
{
  return msg.c_str(); // msg lives as long as this SocketException instance 
}

SocketException如果在对象死亡后指针没有被取消引用,这已经定义了行为。

于 2013-02-10T21:41:53.413 回答
0

怎么样
throw std::runtime_error("My very own message");

于 2014-10-08T13:06:11.537 回答