Как решить конфликт имен при использовании заголовков c? - PullRequest
1 голос
/ 26 ноября 2008

В настоящее время я занимаюсь программированием сокетов с использованием C / C ++. Чтобы иметь возможность использовать несколько более чистый интерфейс и более OO-структуру, я решил написать несколько простых классов-оболочек для частей API сокета C, но при этом наткнулся на проблему:

С учетом следующего кода:

// 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()

Переименование метода класса решает проблему.

Почему возникает какой-то конфликт имен, хотя сигнатуры методов разные? Каков наилучший способ исправить это?

Спасибо / Erik

Ответы [ 3 ]

8 голосов
/ 26 ноября 2008

Проблема в том, что он сначала просматривает область вашего класса и находит функцию foo. Поиск остановится, и компилятор попытается сопоставить аргументы. Поскольку в этой области в вашем классе есть только одна функция foo, вызов функции завершается неудачей.

Вам нужно явно указать, что вы хотите вызвать бесплатную функцию:

::foo(1);

Другое решение - объявить функцию в baz:

void baz() { int foo(int); foo(1); }

Область действия, в которой предполагается, что функция foo определена, является окружением пространства имен вашего класса.

3 голосов
/ 26 ноября 2008

Вы должны использовать разрешение области try:

:: Foo (1);

2 голосов
/ 26 ноября 2008

Решение:

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 предоставляет ссылку в комментарии ниже, объясняющую, как ее разорвать.

...