C++外部:指针与引用

C++ extern: pointer vs. reference

本文关键字:引用 指针 外部 C++      更新时间:2023-10-16

我有三个类:ConsoleInputStreamConsoleOutputStreamConsoleErrorStream。它们都来源于CCD_ 4。

每个流具有虚拟函数readwrite;正如您所猜测的,当用户尝试使用ConsoleInputStreamwrite成员函数时,它会抛出一个错误。当用户尝试使用ConsoleOutputStreamwrite函数时,也会发生同样的情况。

现在是时候展示代码了。

// 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

它对应于取消引用的指针的赋值,而不是普通指针。换言之,如果stdoutstdin是指针,则等效代码将是

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

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

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

您是如何在流上定义赋值的?使用参考声明:

streamlib::stdout = streamlib::stdin;

将第二个引用引用的内容指定为由第一个引用。

在涉及继承的情况下支援任务;例如,在这种情况下,没有办法你的ConsoleOutputStream可以变成一个ConsoleInputStream,这意味着派遣条件可能无法满足。通常解决方案是基类定义一个私有赋值运算符,而不是实现它。您也可以从boost::noncopyable(但这也会抑制副本—您可能想要也可能不想要)。如果你正在使用C++11,一个更好的解决方案是标记作业操作员已删除。

最后,关于指针:您不需要动态使用指针的分配;可以使用初始化指针另一个对象的地址。它似乎起作用的原因使用指针是指分配指针会导致指针正在重新密封。如果ab是参考,则使用指针的CCD_ 31的等价物将是CCD_。