我想抛出有意义解释的异常(套接字句柄,进程ID,网络接口索引......)! 我想使用变量参数工作正常,但最近我发现,为了实现其他异常类型,不可能扩展类。所以我想出了使用std :: ostreamstring作为内部缓冲区来处理格式化......但是没有编译! 我想它有一些东西可以处理复制构造函数。 无论如何这是我的代码片段:
class Exception: public std::exception {
public:
Exception(const char *fmt, ...);
Exception(const char *fname,
const char *funcname, int line, const char *fmt, ...);
//std::ostringstream &Get() { return os_ ; }
~Exception() throw();
virtual const char *what() const throw();
protected:
char err_msg_[ERRBUFSIZ];
//std::ostringstream os_;
};
变量argumens构造函数不能继承!这就是为什么我想到了std :: ostringstream! 关于如何实施这种方法的任何建议?
答案 0 :(得分:2)
传递...
个参数有点尴尬,但可能。您需要先将它们转换为va_list
。因此,为了使您的派生类能够将格式和参数传递给其基类,可以执行以下操作:
class Exception: public std::exception {
public:
Exception(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
this->init(fmt, ap);
va_end(ap);
}
virtual const char *what() const throw();
protected:
Exception(); // for use from derived class's ctor
void init(char const* fmt, va_list, ap)
{
vsnprintf(err_msg_, sizeof err_msg_, fmt, ap);
}
char err_msg_[ERRBUFSIZ];
};
struct Exception2 : Exception
{
Exception2(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
this->init(fmt, ap);
va_end(ap);
}
};
答案 1 :(得分:2)
我认为你的意思是问题是ostringstream
不是可复制构造的。
如果我理解正确,
如何使ostringstream
成员成为std/boost::shared_ptr
之类的指针?
例如:
#include <exception>
#include <sstream>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
struct E : std::exception {
boost::shared_ptr< std::ostringstream > os_;
mutable std::string s_;
std::ostringstream &Get() { return *os_; }
const char *what() const throw() {
s_ = os_->str();
return s_.c_str();
}
E() : os_( boost::make_shared< std::ostringstream >() ) {}
~E() throw() {}
};
int main()
{
try {
E e;
e.Get() << "x";
throw e;
}
catch ( std::exception const& e ) {
cout<< e.what() <<endl;
}
}
希望这有帮助。
答案 2 :(得分:2)
通常,最佳解决方案是为不同的异常定义专用的异常类型。您的SocketException
类型将接受套接字句柄等。这消除了在ctor中对vararg ...
参数的需要。
此外,您不需要std::ostringstream os_
成员。 ostringstream
对象通常用于格式化文本,但不用于存储结果。为此,请使用普通的std::string
。