如何在使用c头时解决名称冲突?

时间:2008-11-26 12:58:03

标签: c++ c scope

我目前正在使用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()

重命名类方法可以解决问题。

为什么即使方法签名不同,也存在某种命名冲突?解决这个问题的最佳方法是什么?

由于 /埃里克

3 个答案:

答案 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在下面的评论中提供了一个链接,解释了如何破坏它。