我有一个基于CPPUNIT库的测试程序和运行~900单元测试的Qt。该程序使用QtCreator部署在Android上。它与~80个库相连,每个库都定义了一些测试。
代码更改后,由于std::bad_cast
被抛出,测试程序开始崩溃。
原始代码(无bad_cast):
class TimeUnit
{
friend std::ostream& operator<<(std::ostream &os, const TimeUnit& var);
public:
std::string TimeUnit::toString() const
{
std::stringstream stream;
static std::string facetStr = "%Y/%m/%d %H:%M";
stream.imbue(std::locale(std::locale::classic(), new boost::posix_time::time_facet(facetStr.c_str())));
stream << *m_time;
return stream.str();
}
private:
boost::posix_time::ptime m_time;
};
std::ostream& operator<<(std::ostream &os, const TimeUnit& var)
{
os << var.toString();
return os;
}
新代码(让测试程序在某些时候抛出bad_cast):
class TimeUnit
{
friend std::ostream& operator<<(std::ostream &os, const TimeUnit& var);
public:
std::string TimeUnit::toString() const
{
std::stringstream stream;
stream << *this;
return stream.str();
}
private:
boost::posix_time::ptime m_time;
};
std::ostream& operator<<(std::ostream &os, const TimeUnit& var)
{
static std::string facetStr = "%Y/%m/%d %H:%M";
os.imbue(std::locale(std::locale::classic(), new boost::posix_time::time_facet(facetStr.c_str())));
// this next line ends up throwing std::bad_cast!
os << *(var.m_time);
return os;
}
我的std::bad_cast
会在某个时刻抛出新代码operator<<
异常。根据{{3}}:
当dynamic_cast引用时,抛出此类型的异常 类型未通过运行时检查(例如,因为类型不相关 通过继承),以及来自std :: use_facet的请求方面 在语言环境中不存在。
... operator<<
boost::posix_time::ptime
use_facet
std::cout
...
经过大量调查后,我可以得出结论:
std::stringstream
(在新代码中,如果我创建一个本地os << str.str()
将方面应用于它,稍后将结果复制为os.imbue(std::locale(std::locale::classic(),...)
,否更多崩溃)os.imbue(std::locale(os.getloc(),...))
或os.imbue
都会导致同样的崩溃os.imbue(std::locale::classic());
电话会使崩溃消失operator<<
返回之前致电operator<<
无法解决问题不幸的是,我试图在MCVE中隔离问题,但无法用一些更基本的代码重现问题......
所以我的问题是(是):
bad_cast
修改
经过一些调查后,我发现如果我将std::cout
重定向到我的主文件,只会抛出class ScopedRedirect
{
public:
ScopedRedirect(std::ostream & inOriginal, std::ostream & inRedirect) :
mOriginal(inOriginal),
mOldBuffer(inOriginal.rdbuf(inRedirect.rdbuf()))
{}
virtual ~ScopedRedirect()
{
mOriginal.rdbuf(mOldBuffer);
}
ScopedRedirect(const ScopedRedirect&) = delete;
ScopedRedirect& operator=(const ScopedRedirect&) = delete;
protected:
std::ostream & mOriginal;
std::streambuf * mOldBuffer;
};
int main( int argc, char* argv[] )
{
std::fstream output( "cout.txt", std::ios_base::out );
assert( output.is_open() );
ScopedRedirect redirectCount( std::cout, output );
...
}
,使用:
springProperty