【问题标题】:Method overloading in CC中的方法重载
【发布时间】:2013-04-14 01:48:42
【问题描述】:

既然 C 不支持方法重载,怎么可能有像 open 这样显式提供两种不同签名的方法:

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

我的意思是,printf 支持使用 vargs 的各种参数,但除了使用 vargs 本身的参数之外没有明确的签名——否则应该有一个签名 for each possible printf 调用。然而,open()——据我推测——是用 C 语言编写的,并提供了两个显式签名。

我并没有真正了解这些功能的实现方式。有人可以举一个小例子来说明一个函数如何:

void foo() { printf("bar\n"); }
void foo(int x) { printf("bar %d\n", x); }

会在 C 中实现吗?

【问题讨论】:

  • 我之前也问过类似的问题,请参考:[这里][1][1]:stackoverflow.com/questions/3953895/…
  • @GreenCode 我搜索了方法重载,但你的问题没有出现;这就是我问的原因。 +1 感谢您的参考。

标签: c overloading


【解决方案1】:

函数open 定义了可变数量的参数:

int open(const char *_path, int _oflag, ...)

这里是<fcntl.h>的来源;函数open 使用_PROTOTYPE 宏在底部声明。

请注意,它与open 一起使用的部分原因是该函数已经接受了其他参数。为了让函数接受可变数量的参数,它必须至少接受一个“固定”参数。这就是为什么不能用你的foo() 函数做这个技巧的原因。

【讨论】:

  • +1 感谢您的解释。现在我假设函数open(),除了接受至少一个参数之外,还使用一些“assertion”来在编译时检查错误数量的参数,对吧?
  • @Rubens 编译器无法进行其他编译时检查:它将标准类型提升应用于第三个参数(以及您可能选择传递的任何其他参数,因为调用 open有四个甚至四十个论点是可能的)。我想正在进行一些运行时检查,但编译器在检查 _oflag 以外的参数方面非常有限。
【解决方案2】:

您选择了一个较差的参考 (http://linux.die.net) 来了解此功能。一个更好的是Open Group Base Specifications。它显示了open() 的声明:

int open(const char *path, int oflag, ... );

换句话说,这只是可变参数。

【讨论】:

    【解决方案3】:

    怎么可能有像 open 这样明确提供两种不同签名的方法:

    等等,等等,等等……不。差远了。怎么样reading the documentation?

    open()是一个可变参数函数,它的签名是

    int open(const char *path, int oflag, ... );
    

    这里没有魔法。

    【讨论】:

    • 在某些发行版上 man 2 open 产生具有这些签名的文档: int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode); ,因此造成混乱。
    【解决方案4】:

    它都是基于可变参数的。在打开的情况下,它只读取某些输入和状态的第三个参数。特别是当它必须创建文件时。同样, printf 仅在扫描 % 格式标记时读取参数。您的案例并没有真正起作用,因为没有早期参数表明有多少参数。

    【讨论】:

      【解决方案5】:

      您不能在程序中定义同名函数超过 1 次,正如您在问题中提到的那样

      使用宏将允许您在 C 代码中定义函数超过 1 次,但只会编译 1 个函数

      #ifdef MACRO1
      void foo() { printf("bar\n"); }
      #else
      void foo(int x) { printf("bar %d\n", x); }
      #endif
      

      主要是

      #ifdef MACRO1
          foo();
      #else
          foo(5);
      #endif
      

      【讨论】:

      • 但这是否允许第一个和第二个方法调用,就像open() 函数一样?我不确定,但我想我可以在主文件中同时使用 open() 的两个调用,不是吗?
      猜你喜欢
      • 2011-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-07
      • 2016-04-01
      • 1970-01-01
      相关资源
      最近更新 更多