【问题标题】:Is it OK to define operator<< or operator>> for FILE&?可以为 FILE& 定义 operator<< 或 operator>> 吗?
【发布时间】:2014-06-23 05:37:09
【问题描述】:

这听起来像是一个奇怪的问题,但我是否可以安全地为 FILE 对象定义 operator&lt;&lt;operator&gt;&gt;,或者我会违反 C 或 C++ 标准中的潜在条款,还是可能导致其他问题?

(是的,我确实了解 C++ I/O 流。我问这是否是一个的主意。我我在问它是否允许。)

例子:

#include <stdio.h>

FILE &operator>>(FILE &file, int &d)
{
    if (fread(&d, sizeof(d), 1, &file) != 1)
    { throw "I/O error"; }
    return file;
}

int main()
{
    int x;
    FILE *file = fopen("File.bin", "rb");
    *file >> x;
    fclose(file);
    return x;
}

【问题讨论】:

  • 我认为这与 C 无关。
  • @JonathonReinhart:C 标准有一个stdio.h,实际上我引用了它。我认为 C++ 标准在这里确实遵循 C。
  • 允许在高速公路中间玩耍……但这不是一个的主意。尝试一下! (重载 FILE 运算符,而不是在街上玩。)这是你的代码!不会破坏任何东西!
  • @lornix:我实际上认为在某些地方在高速公路中间玩耍可能是非法的。 =P
  • @Praetorian:这并不要求它是一个完整的类型,是吗?它被转换为引用,而不是值。

标签: c++ c operator-overloading language-lawyer


【解决方案1】:

暂时忽略这是否是一个好主意的问题(但事实并非如此),这是否真的被允许存在疑问。

C++ 标准定义了所有相关的头文件和函数——&lt;cstdio&gt; 包含在 §27.9.2 中。如果您真的想使用它,&lt;stdio.h&gt; 甚至是 C++ 标准(§D.5)的一部分,尽管它已被正式弃用。

这往往表明它是允许的。 C 标准(§7.19.1/2)的措辞是:

        FILE

这是一种对象类型,能够记录控制一个对象所需的所有信息 流,包括其文件位置指示符、指向其关联缓冲区的指针(如果有)、记录是否发生读/写错误的错误指示符以及文件结尾 记录是否已到达文件末尾的指示器;

问题是FILE 是否真的需要直接表示该类型,或者(例如)可以是typedefd 到void,所以(例如)fopen 实际上返回一个@987654328 @。使用它的库内部会将其转换为正确的类型,但对于外部世界(即您的程序)来说,它是完全不透明的。特别是,如果它是void *,则不能取消引用它,甚至不能只获取引用而不是指针。

我猜这主要是理论上的。我认为一般来说,假设 FILE 是一个独特的类型,你可以在它上面进行重载是相当安全的。您不应该假设它所指向的内部结构,但是假设您可以取消引用它以获取引用而不是指针,那么您是相当安全的(并且假设重载将与其他类型的重载区分开来是相当安全的比如整数)。

【讨论】:

  • 不,void 不是对象类型,而是例如char[128] 是,struct __real_file* 也是。如果您的 impl 具有 1024 位 int,那么 int1024_t 也符合条件。两者都不能超载。
  • @n.m.您应该能够在struct __real_file* 上超载。真正的问题是int1014_t
  • 您始终可以创建一个瘦类型包装器,在该包装器上使用运算符重载,然后使用标准 API 直接作用于 FILE*。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-25
  • 2011-04-22
  • 1970-01-01
  • 2020-09-20
  • 2019-06-05
  • 2016-12-05
相关资源
最近更新 更多