在我的代码中,我的类的init函数是这样的:
void MyApp::start(std::ostream & log_output)
{
theLogOutput = log_output;
// do stuff...
}
和theLogOutput
被声明为.h文件:
std::ostream theLogOutput;
但是编译器给了我这个错误:
Error 10 error C2248: 'std::basic_ostream<_Elem,_Traits>::operator =' : cannot access private member declared in class 'std::basic_ostream<_Elem,_Traits>'
答案 0 :(得分:2)
std::ostream
不可复制;它有可变状态,是
多态,这使复制和分配有问题。在
C ++ 11,它是可移动的,如果你想让调用者放弃所有
posession(但你必须明确地移动它)。大部分的
但是,时间,你不需要字符串的副本,也不是唯一的
所有权;在这些情况下,您将成员作为引用
好吧,或者如果班级必须支持作业,你就做了
成员指针,并获取参数的地址。
在您的情况下,由于您正在修改已存在的变量, 你需要使用指针;必须初始化引用,并且 一旦初始化,就无法重新安装。
答案 1 :(得分:1)
通过引用传递在这里工作正常,问题是theLogOutput = log_output
会产生副本。
正如评论者指出的那样,std::ostream
无法复制(因为它没有复制构造函数)。你可以做一些事情:
log_output
对象的生命周期是静态的(或者足够长),则可以使全局日志流成为std::ostream
的指针,并使其保存所述对象的地址(即{ {1}},您可以考虑将流作为指针,以使意图更清晰)。例如,这适用于您在theLogOutput = &log_output
中本地分配的std::cout
,std::cin
或任何std::ostream
。请务必将文档中的生命周期要求说明为main
。startApp
来保持对单个流的共享引用。std::shared_ptr<std::ostream>
最后但同样重要的是,在std::ostream
文件中声明全局变量并不是一个好主意。如果文件包含在多个翻译单元中,则由于多次定义符号而导致错误。最多应该在标题中声明.h
,并且只在一个翻译单元(.cpp文件)中定义。