[英]C++ extern: pointer vs. reference
我有三个类: ConsoleInputStream
, ConsoleOutputStream
, ConsoleErrorStream
。 所有这些都来自Stream
。
每个流有虚函数read
和write
; 如你所想,当用户尝试使用ConsoleInputStream
的write
成员函数时,它会抛出一个错误。 当用户尝试使用ConsoleOutputStream
的write
函数时ConsoleOutputStream
发生同样的情况。
现在是时候展示代码了。
// STREAM.HPP
namespace streamlib {
extern ConsoleInputStream stdin_default;
extern ConsoleOutputStream stdout_default;
extern ConsoleErrorStream stderr_default;
extern Stream& stdin;
extern Stream& stdout;
extern Stream& stderr;
} // namespace streamlib
// STREAM.CPP
namespace streamlib {
ConsoleInputStream stdin_default;
ConsoleOutputStream stdout_default;
ConsoleErrorStream stderr_default;
Stream& stdin = stdin_default;
Stream& stdout = stdout_default;
Stream& stderr = stderr_default;
} // namespace streamlib
// MAIN.CPP
int main()
{
streamlib::stdout = streamlib::stdin;
streamlib::stdout.write(); // Still working, but should have thrown error!
}
但是,当我将stdin
, stdout
和stderr
定义为指针而不是引用时,一切都运行良好,即错误按预期抛出。 但我不想分配/释放内存并使用->
运算符,我可以(我可以?)使用普通点运算符。
实际情况当然更复杂:我还有一些从Stream
派生的其他类型,只是希望能够使用不同类型的流快速重载stdin
, stdout
, stderr
流。 有可能用引用来做吗?
提前致谢!
你是如何在你的溪流上定义作业的? 随着参考声明:
streamlib::stdout = streamlib::stdin;
将第二个引用所指的内容分配给第一个引用的内容。
在涉及继承的情况下,支持转让通常是一个坏主意; 例如,在这种情况下, ConsoleOutputStream
无法成为ConsoleInputStream
,这意味着可能无法满足正常的分配条件。 通常的解决方案是基类定义一个私有赋值运算符,而不是实现它。 你也可以从boost::noncopyable
派生(但这也会抑制你可能想要或不想要的副本)。 如果您使用的是C ++ 11,更好的解决方案是将赋值运算符标记为已删除。
最后,关于指针:你不需要动态分配来使用指针; 您可以使用另一个对象的地址初始化指针。 它似乎与指针一起工作的原因是分配指针会导致指针被重置。 如果a
和b
是引用,那么使用指针的a = b
的等价物将是*a = *b
。
您无法使用引用执行的操作,因为无法重新分配引用。 当你这样做参考
streamlib::stdout = streamlib::stdin
它对应于解除引用指针的赋值,而不是普通指针。 换句话说,如果stdout
和stdin
是指针,那么等价的代码就是
(*streamlib::stdout) = (*streamlib::stdin)
这将调用Stream
的赋值运算符,将stdin
传递给stdout
。
解决此问题的一种方法是定义一个可分配的“指针流”,它封装一个指向“实际”流的指针,并在指定时通过指向它的任何流的指针覆盖它。 这将允许您保留对象语法,让您使用点.
运算符而不是指针解引用运算符->
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.