-4

让这成为示例代码:

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

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

4

1 回答 1

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

铛:

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++ Reference 所说的std::basic_ostream 复制构造函数

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


解释:

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;
于 2019-03-18T01:10:49.373 回答