无法使用ostream进行打印,但可以使用cout进行打印?

时间:2019-03-11 14:00:55

标签: c++ polymorphism protected ostream

这是示例代码:

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

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

1 个答案:

答案 0 :(得分:0)

问题:

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>]'

C语:

  

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

C语:

  

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复制到变量{ {1}}。

但是该类的定义表明不能使用复制构造函数,因此编译器会给出错误消息。

2)在创建变量output的情况下-它没有提供任何构造函数参数,因此没有默认构造函数,因此编译器会给出错误消息。


如何解决此问题?

1)在函数的声明中,更改定义以将os的引用(&)作为参数:

std::ostream

这允许它使用原始对象代替复制(不允许复制)。


2)如果需要变量,则还应该使用引用;

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