【C++】关于std::ostream的构造函数

参考博客:https://blog.csdn.net/e21105834/article/details/115859154

一、问题

写了一段代码相对输出流std::osteam进行操作,可是却一直报错,代码如下:

#include <iostream>
#include <sstream>
#include <string>

using namespace std;

int main(int argc, char* argv[]) 
{
    ostream os;
	stringstream ss1(argv[1]);
	os << "ss1:" << ss1.str() << endl;
	ss1 >>  hex >> supi;
	os << "supi:" << supi << endl;
	cout << endl;
	getchar();
	return 0;
}

猛一看,貌似没什么问题,但出现错误如下:

错误:'std :: basic_ostream&lt; _CharT,_Traits&gt; :: basic_ostream()[with _CharT = char;

但是在operator<<重载时却可以使用,让我产生了困惑:

friend std::ostream & operator<<(std::ostream& os, const int& a) {
    os << a;
    return os;
}

 

二、错误原因

后来,查看了下std::ostream的构造函数,如下:

public:
//explicit用来防止由构造函数定义的隐式转换
explicit
      basic_ostream(__streambuf_type* __sb)
      { this->init(__sb); }

protected:
      basic_ostream()
      { this->init(0); }

#if __cplusplus >= 201103L
      // Non-standard constructor that does not call init()
      basic_ostream(basic_iostream<_CharT, _Traits>&) { }

      basic_ostream(const basic_ostream&) = delete;

      basic_ostream(basic_ostream&& __rhs)
      : __ios_type()
      { __ios_type::move(__rhs); }

      // 27.7.3.3 Assign/swap

      basic_ostream& operator=(const basic_ostream&) = delete;

      basic_ostream&
      operator=(basic_ostream&& __rhs)
      {
	swap(__rhs);
	return *this;
}

可以看到ostream类的默认构造函数是保护类型,而带参数的构造函数则是公有的,根据public和protected的功能,我们要定义一个ostream对象,必须要在参数中传入streambuf类型的指针才可以,否则会报编译错误。

下面使用一个例子说明:

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
	filebuf buf;
	if ( buf.open("/proc/self/fd/1", ios::out) == nullptr )
	{
		cerr << "stdout open failed" << endl;
		return -1;
	}
	ostream out(&buf);
	return 0;
}

总结:std::ostreamstd::istreamstd::iostreamstd::stringstreamstd::fstream等类的基类。这些类构造函数是保护类型,是不允许拷贝或者赋值的,所以它也不能直接作为返回类型和参数传递,很多时候需要使用引用来进行传递。所以只能实例化其派生类,然后使用引用或者指针来指向实例实现调用。(streambuf也一样,所以上面使用了其子类filebuf)

三、解决办法

最后,还是回到开始的问题,如何解决。这里提供了一种便捷方法,将std::cout控制台输出流实例赋给std::ostream就可以了。

#include <iostream>
#include <sstream>
#include <string>

using namespace std;

int main(int argc, char* argv[]) 
{
    ostream &os = std::cout;
	stringstream ss1(argv[1]);
	os << "ss1:" << ss1.str() << endl;
	ss1 >>  hex >> supi;
	os << "supi:" << supi << endl;
	cout << endl;
	getchar();
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值