Mik*_*kan 3 c++ overloading declaration function
我目前定义了多次重载的函数。对于某些重载的定义,它使用不同的输入类型调用相同的函数。因此,将函数Foo定义为采用类型A,但在函数主体内,它将对类型B调用Foo。但是,对类型B的Foo的定义是在定义A之后。
我目前在编译时出错,我认为这是由于重载定义的顺序所致。我没有明确的错误消息或调试工具,因此我想知道上述情况是否确实导致了错误。
void Foo (A input) {
B b = B();
Foo(b);
}
void Foo (B input) {
printf("%s", input.toString());
}
int main() {
A a = A();
Foo(a);
return 0;
}
//code has been oversimplified
Run Code Online (Sandbox Code Playgroud)
我认为这个问题可以归结为“编译器只检查是否已定义函数,还是只检查特定输入上是否已定义函数?”
在以下等价的意义上,重载的声明顺序无关紧要:
// 1.
void foo(int);
void foo(double);
foo(42);
// 2.
void foo(double);
void foo(int);
foo(42);
Run Code Online (Sandbox Code Playgroud)
重载的声明顺序在以下不相等的意义上很重要:
// 3.
void foo(int);
foo(42);
void foo(double);
// 4.
void foo(double);
foo(42);
void foo(int);
Run Code Online (Sandbox Code Playgroud)
简而言之:只有在函数调用之前已声明的函数才可以参与重载解析。
在您的示例程序中,Foo(A)或者具有无限递归(如果B隐式转换为A),或者由于您Foo(B)在调用之前未进行声明,因此该程序格式错误。
编译器是否仅检查功能是否已定义
通常,编译器根本不会检查是否已定义函数。但是,必须先声明函数,然后才能调用它。
简短的回答是肯定的 - 顺序很重要。(此外,它实际上与重载无关 - 您可以重命名Foo(B)为Goo(B)。)
针对您的特定问题的一种常见补救措施是转发声明Foo(B):
// Forward declaration
void Foo(B);
void Foo (A input) {
B b = B();
Foo(b); // Compiler now knows about Foo(B), so this is fine.
}
void Foo (B input) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
编译器需要了解该特定函数 - 它必须在使用之前已被声明。但是,它可以在其他地方定义。在链接时,所有编译器输出都被收集,并且符号被“链接”在一起 - 链接器将弄清楚如何生成正确的指令以Foo(B)从该行调用,或者可能内联它,等等。
有时可能必须预先声明该函数。例如
void Foo() {
if (condition) Goo();
}
void Goo() {
if (condition) Foo();
}
Run Code Online (Sandbox Code Playgroud)
两者Foo都Goo需要相互了解,因此您可以在Foo()的定义之前声明两者(或者将它们放在标头中,如果合适的话)。