繁体   English   中英

C ++ extern:指针与引用

[英]C++ extern: pointer vs. reference

我有三个类: ConsoleInputStreamConsoleOutputStreamConsoleErrorStream 所有这些都来自Stream

每个流有虚函数readwrite ; 如你所想,当用户尝试使用ConsoleInputStreamwrite成员函数时,它会抛出一个错误。 当用户尝试使用ConsoleOutputStreamwrite函数时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!
}

但是,当我将stdinstdoutstderr定义为指针而不是引用时,一切都运行良好,即错误按预期抛出。 但我不想分配/释放内存并使用->运算符,我可以(我可以?)使用普通点运算符。

实际情况当然更复杂:我还有一些从Stream派生的其他类型,只是希望能够使用不同类型的流快速重载stdinstdoutstderr流。 有可能用引用来做吗?

提前致谢!

你是如何在你的溪流上定义作业的? 随着参考声明:

streamlib::stdout = streamlib::stdin;

将第二个引用所指的内容分配给第一个引用的内容。

在涉及继承的情况下,支持转让通常是一个坏主意; 例如,在这种情况下, ConsoleOutputStream无法成为ConsoleInputStream ,这意味着可能无法满足正常的分配条件。 通常的解决方案是基类定义一个私有赋值运算符,而不是实现它。 你也可以从boost::noncopyable派生(但这也会抑制你可能想要或不想要的副本)。 如果您使用的是C ++ 11,更好的解决方案是将赋值运算符标记为已删除。

最后,关于指针:你不需要动态分配来使用指针; 您可以使用另一个对象的地址初始化指针。 它似乎与指针一起工作的原因是分配指针会导致指针被重置。 如果ab是引用,那么使用指针的a = b的等价物将是*a = *b

您无法使用引用执行的操作,因为无法重新分配引用。 当你这样做参考

streamlib::stdout = streamlib::stdin

它对应于解除引用指针的赋值,而不是普通指针。 换句话说,如果stdoutstdin是指针,那么等价的代码就是

(*streamlib::stdout) = (*streamlib::stdin)

这将调用Stream的赋值运算符,将stdin传递给stdout

解决此问题的一种方法是定义一个可分配的“指针流”,它封装一个指向“实际”流的指针,并在指定时通过指向它的任何流的指针覆盖它。 这将允许您保留对象语法,让您使用点. 运算符而不是指针解引用运算符->

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM