C ++ extern:指针与引用

时间:2013-11-19 12:05:34

标签: c++ extern

我有三个课程:ConsoleInputStreamConsoleOutputStreamConsoleErrorStream。所有这些都来自Stream

每个流都有虚函数readwrite;如你所想,当用户尝试使用ConsoleInputStream的{​​{1}}成员函数时,会抛出错误。当用户尝试使用write的{​​{1}}函数时也会发生相同的情况。

现在是时候展示代码了。

ConsoleOutputStream

但是,当我将write// 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,{{1具有不同种类的流的流。可以用引用来做吗?

提前致谢!

2 个答案:

答案 0 :(得分:3)

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

streamlib::stdout = streamlib::stdin;

指定第二个引用引用的内容 第一个提到的。

如果涉及继承,通常是一个坏主意 支持任务;在这种情况下,例如,没有办法 您的ConsoleOutputStream可以成为 一个ConsoleInputStream,这意味着正常的帖子 任务条件可能无法满足。通常 解决方案是为基类定义一个私有赋值 运算符,而不是实现它。你也可以从中衍生出来 boost::noncopyable(但这也会压制 复制 - 您可能想要也可能不想要)。如果你正在使用 C ++ 11,更好的解决方案是标记赋值 运算符已删除。

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

答案 1 :(得分:3)

您无法使用引用执行的操作,因为无法重新分配引用。当您执行此操作时

streamlib::stdout = streamlib::stdin

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

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

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

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