C++中ostringstream转ostream生效反向失败及curl响应获取问题咨询
问题1:ostringstream与ostream类型转换问题
问题原因
- 首先明确类的继承关系:
std::ostringstream是std::ostream的公有派生类,C++中公有派生类的引用/指针可以隐式转换为基类的引用/指针(向上转型,属于安全转换,转换后只能调用基类定义的接口),所以第一部分代码可以正常运行。 - 第二部分代码存在两个错误:
- 不能直接实例化
std::ostream对象:std::ostream作为抽象基类,默认构造函数是protected权限,只有派生类构造时可以调用,普通代码直接构造ostream os2本身就会触发你看到的编译错误。 - 基类到派生类的向下转型默认不支持:即使你有一个实际指向派生类对象的基类引用/指针,隐式转换也不被允许,需要手动使用
dynamic_cast做安全检查后转换。
- 不能直接实例化
修复方案
如果你的需求是将绑定了派生类实例的基类引用转换为派生类引用,参考以下代码:
int main() { ostringstream oss; ostream& os=oss ; // 向下转型,先转指针判断是否转换成功 ostringstream* oss_ptr = dynamic_cast<ostringstream*>(&os); if(oss_ptr != nullptr) { // 转换成功,说明os实际绑定的是ostringstream对象,可以正常使用 cout <<"address is "<< oss_ptr << endl; } return 0; }
问题2:curlCall函数内部获取请求响应问题
实现方案
不需要修改函数参数,利用C++的运行时类型识别功能,对传入的ostream引用做动态类型转换即可:
你当前调用时传入的是ostringstream类型的对象,执行完curl_easy_perform后响应内容已经写入到这个流对象中,只需要将基类引用转换为派生类ostringstream的指针,调用str()方法就可以直接在curlCall内部拿到响应内容。
代码修改示例
void curlCall(ostream& os) { CURL* curl=curl_easy_init(); curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,&CurlDataWrite); // 补充说明:CURLOPT_FILE是兼容旧版本的宏,推荐替换为CURLOPT_WRITEDATA,功能完全一致 curl_easy_setopt(curl,CURLOPT_WRITEDATA,&os); curl_easy_setopt(curl,CURLOPT_URL, "https://something.com"); int code=curl_easy_perform(curl); // 新增以下代码获取响应 ostringstream* oss_ptr = dynamic_cast<ostringstream*>(&os); if(oss_ptr != nullptr) { // 转换成功,直接获取响应 std::string response = oss_ptr->str(); // 这里就可以对response做任意处理 std::cout << "curlCall内部拿到的响应:" << response << std::endl; } // 释放curl资源 curl_easy_cleanup(curl); }
边界情况说明
如果外部传入的ostream不是ostringstream类型(比如传入的是std::cout),dynamic_cast会返回空指针,此时可以根据业务需求做降级处理。
内容的提问来源于stack exchange,提问作者sumit1024
相关产品推荐
相关产品推荐

