无法使用 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]-&gt;view(os) 进行视频输出?如果我使用v[i]-&gt;view(os),它会说:

'std::basic_ostream&lt;_CharT, _Traits&gt;::basic_ostream() [with _CharT = char; _Traits = std::char_traits&lt;char&gt;]' is protected

虽然这对于视频输出是正确的,但对于保存功能却不是这样,它可以正常工作,正如代码中所预期的那样。有人可以解释吗?对不起,如果我弄长了

【问题讨论】:

我们能不能看一下不起作用的代码,包括view是如何定义的(请minimal reproducible example)? 您显示的代码均未提及std::ostream。错误消息来自其他代码。发布该代码。但是从描述中问题就很清楚了。 std::ostream 旨在用作输出流的基类。 std::ostream os; 不打算工作,编译器正确地抱怨。 std::ostream 只是一个接口类,你需要一个子类(例如ofstreamostringstream)来做一些有用的事情。您得到的错误是只有子类可以调用ostream 构造函数的消息,提示“查找子类”。 Why is protected constructor raising an error this this code?的可能重复 顺便说一句 std::coutostream 【参考方案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&lt;char,std::char_traits&lt;char&gt;&gt;::basic_ostream(const std::basic_ostream&lt;char,std::char_traits&lt;char&gt;&gt; &amp;)': attempting to reference a deleted function

海合会:

error: use of deleted function 'std::basic_ostream&lt;_CharT, _Traits&gt;::basic_ostream(const std::basic_ostream&lt;_CharT, _Traits&gt;&amp;) [with _CharT = char; _Traits = std::char_traits&lt;char&gt;]'

叮当声:

error: call to deleted constructor of 'std::ostream' (aka 'basic_ostream&lt;char&gt;')


2) 对于声明

std::ostream os;

显示以下错误信息:

MSVC:

error C2512: 'std::basic_ostream&lt;char,std::char_traits&lt;char&gt;&gt;': no appropriate default constructor available

海合会:

error: 'std::basic_ostream&lt;_CharT, _Traits&gt;::basic_ostream() [with _CharT = char; _Traits = std::char_traits&lt;char&gt;]' is protected within this context

叮当声:

error: calling a protected constructor of class 'std::basic_ostream&lt;char&gt;'


原因:

这都是按照std::basic_ostream的规范来的

没有默认构造函数的定义 - 因此,如果没有特定的构造函数参数,就无法创建 std::ostream 类型的变量。

正如 C++ 参考所说,std::basic_ostream copy constructor:

复制构造函数受到保护,并被删除。输出流不可复制。


解释:

1) 所以问题是在(2) 中,参数std::cout 被传递给在(1) 中定义的函数,以将std::ostream 复制到变量output

但是类的定义说不能使用拷贝构造函数,所以编译器报错。

2) 在创建变量os的情况下——它没有给出任何构造函数参数,没有默认构造函数,所以编译器给出了错误信息。


如何解决这个问题?

1) 在函数的声明中更改定义以将 std::ostream 的引用 (&amp;) 作为参数:

void view(std::ostream& output, std::string text) // (1)

这允许它使用原始对象而不是制作副本(不允许复制)。


2) 如果需要一个变量,那么也应该使用一个引用;

std::ostream& out = std::cout;

【讨论】:

以上是关于无法使用 ostream 打印,但可以使用 cout 打印?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用ostream在c ++中打印unsigned char作为十六进制?

输入和输出运算符

如何使用 gdb 制作一个可以漂亮地打印每个对象的 C++ 函数?

为啥 ostream 为定义为 `volatile char[]` 的字符串打印 `1`? [复制]

在 ostream 重载友元函数中使用向量

使用 Boost HOF 实现 STL 漂亮打印