无法使用 ostream 打印,但可以使用 cout 打印?
Posted
技术标签:
【中文标题】无法使用 ostream 打印,但可以使用 cout 打印?【英文标题】:cannot print using ostream but can by using cout? 【发布时间】:2019-08-01 20:50:05 【问题描述】:让这成为示例代码:
object o1(//parameters);
object o2(//parameters);
object o3(//parameters);
object *v[3];
using std::cout; //video output
ofstream of; //save on file
//let's suppose
v[0]=&o1;
v[1]=&o2;
v[2]=&o3;
for (int i=0;i<3;i++)
v[i]->view(cout);
v[i]->save(of);
view函数只是类参数的视频打印函数,而save函数将类的参数保存在一个文件中。问题是,如果我声明std::ostream;
和ostream os;
为什么不能使用v[i]->view(os)
进行视频输出?如果我使用v[i]->view(os)
,它会说:
'std::basic_ostream<_CharT, _Traits>::basic_ostream() [with _CharT = char; _Traits = std::char_traits<char>]' is protected
虽然这对于视频输出是正确的,但对于保存功能却不是这样,它可以正常工作,正如代码中所预期的那样。有人可以解释吗?对不起,如果我弄长了
【问题讨论】:
我们能不能看一下不起作用的代码,包括view
是如何定义的(请minimal reproducible example)?
您显示的代码均未提及std::ostream
。错误消息来自其他代码。发布该代码。但是从描述中问题就很清楚了。 std::ostream
旨在用作输出流的基类。 std::ostream os;
不打算工作,编译器正确地抱怨。
std::ostream
只是一个接口类,你需要一个子类(例如ofstream
或ostringstream
)来做一些有用的事情。您得到的错误是只有子类可以调用ostream
构造函数的消息,提示“查找子类”。
Why is protected constructor raising an error this this code?的可能重复
顺便说一句 std::cout
是 ostream
【参考方案1】:
问题:
1) 如果view
函数定义为:
void view(std::ostream output, std::string text) // (1)
output << text;
并使用:
view(std::cout, "Hello, World!"); // (2)
然后编译器给出错误信息:
在 MSVC 中:
error C2280: 'std::basic_ostream<char,std::char_traits<char>>::basic_ostream(const std::basic_ostream<char,std::char_traits<char>> &)': attempting to reference a deleted function
海合会:
error: use of deleted function 'std::basic_ostream<_CharT, _Traits>::basic_ostream(const std::basic_ostream<_CharT, _Traits>&) [with _CharT = char; _Traits = std::char_traits<char>]'
叮当声:
error: call to deleted constructor of 'std::ostream' (aka 'basic_ostream<char>')
2) 对于声明
std::ostream os;
显示以下错误信息:
MSVC:
error C2512: 'std::basic_ostream<char,std::char_traits<char>>': no appropriate default constructor available
海合会:
error: 'std::basic_ostream<_CharT, _Traits>::basic_ostream() [with _CharT = char; _Traits = std::char_traits<char>]' is protected within this context
叮当声:
error: calling a protected constructor of class 'std::basic_ostream<char>'
原因:
这都是按照std::basic_ostream的规范来的
没有默认构造函数的定义 - 因此,如果没有特定的构造函数参数,就无法创建 std::ostream
类型的变量。
正如 C++ 参考所说,std::basic_ostream copy constructor:
复制构造函数受到保护,并被删除。输出流不可复制。
解释:
1) 所以问题是在(2)
中,参数std::cout
被传递给在(1)
中定义的函数,以将std::ostream
复制到变量output
。
但是类的定义说不能使用拷贝构造函数,所以编译器报错。
2) 在创建变量os
的情况下——它没有给出任何构造函数参数,没有默认构造函数,所以编译器给出了错误信息。
如何解决这个问题?
1) 在函数的声明中更改定义以将 std::ostream
的引用 (&
) 作为参数:
void view(std::ostream& output, std::string text) // (1)
这允许它使用原始对象而不是制作副本(不允许复制)。
2) 如果需要一个变量,那么也应该使用一个引用;
std::ostream& out = std::cout;
【讨论】:
以上是关于无法使用 ostream 打印,但可以使用 cout 打印?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用ostream在c ++中打印unsigned char作为十六进制?
如何使用 gdb 制作一个可以漂亮地打印每个对象的 C++ 函数?