我目前正在使用C / C ++进行一些套接字编程。为了能够使用更简洁的界面和更多的OO结构,我决定围绕C套接字API的部分编写一些简单的包装类,但在这样做时我偶然发现了一个问题:
给出以下代码:
// Global method
int foo(int x)
{
return x;
}
// Class that calls the global method
class FooBar
{
public:
void foo() { return; };
void baz() { foo(1); }
};
g ++提供以下错误消息:
test.cpp: In member function ‘void FooBar::baz()’:
test.cpp:10: error: no matching function for call to ‘FooBar::foo(int)’
test.cpp:9: note: candidates are: void FooBar::foo()
重命名类方法可以解决问题。
为什么即使方法签名不同,也存在某种命名冲突?解决这个问题的最佳方法是什么?
由于 /埃里克
答案 0 :(得分:8)
问题是它首先查看你的类的范围,并找到一个foo函数。然后查找将停止,编译器尝试匹配参数。由于它只在你的类中具有一个foo函数,因此调用该函数失败。
您需要明确声明要调用自由函数:
::foo(1);
另一个解决方案是在baz中声明函数:
void baz() { int foo(int); foo(1); }
假定foo函数定义的范围是类的周围命名空间。
答案 1 :(得分:3)
您必须使用范围解析试试:
:: foo的(1);
答案 2 :(得分:2)
解决方案是:
void baz() { ::foo(1); }
“为什么即使方法签名不同,也存在某种命名冲突?”
因为C ++始终会首先查找名称。当它在相关范围中找到名称时,它会检查该范围内该名称可用的签名。因此foo()
成员函数会将foo(int)
自由函数隐藏在范围内的任何位置(即,在类的其他成员函数中)。
以下代码无法编译,原因相同:
struct A {
virtual void foo(int) = 0;
// attempt to provide a useful helper
virtual void foo() { foo(23); }
};
struct B : public A {
void foo(int i) {
std::cout << i << "\n";
}
};
int main() {
B b;
b.foo(); // oops, can't find foo(), because class B hid it
A &a = b;
a.foo(); // that works. So much for Liskov's substitution principle.
}
如上所述,B被破坏,因为它从其基类中删除了功能(尽管仅在被称为B时,而不是在被称为A时)。 litb在下面的评论中提供了一个链接,解释了如何破坏它。