Форум программистов, компьютерный форум CyberForum.ru

Дружественная функция, объявлённая ранее вне пространства имён класса -> error LNK2019 в Visual Studio 2012 - C++

Восстановить пароль Регистрация
 
mamucho666
1 / 1 / 0
Регистрация: 06.06.2012
Сообщений: 13
25.12.2012, 17:41     Дружественная функция, объявлённая ранее вне пространства имён класса -> error LNK2019 в Visual Studio 2012 #1
Всем привет. Долгое время пытался откопать ответ в гугле, но не получилось. Заранее благодарен.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void f(){};
namespace space
{
    class ok
    {
        friend void f();
    public:
        ok(){f();}
    };
}
int main() 
{
    space::ok a;
    return 0;
}
В итоге получаю:

Код
1>  main.cpp
1>main.obj : error LNK2019: ссылка на неразрешенный внешний символ "void __cdecl space::f(void)" (?f@space@@YAXXZ) в функции "public: __thiscall space::ok::ok(void)" (??0ok@space@@QAE@XZ)
1>D:\Self-Education\С++\Project\main\Debug\main.exe : fatal error LNK1120: неразрешенных внешних элементов: 1
То есть почему-то объявление функции f() дружественной происходит так, как будто она не была ранее объявлена (в глобальной области), в результате чего её имя помещается в окружающую область видимости - A.

Почему?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.12.2012, 17:41     Дружественная функция, объявлённая ранее вне пространства имён класса -> error LNK2019 в Visual Studio 2012
Посмотрите здесь:

Преобразование типа аргумента в тип класса и дружественная функция C++
Почему дружественная функция с перегруженным оператором << не имеет доступа к данным класса? C++
Обращение к приватному члену класса внутри пространства имён C++
C++ Шаблон класса и дружественная функция
Дружественная функция-оператор, доступ к закрытым полям класса C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Issues
429 / 364 / 37
Регистрация: 06.08.2012
Сообщений: 961
25.12.2012, 19:09     Дружественная функция, объявлённая ранее вне пространства имён класса -> error LNK2019 в Visual Studio 2012 #2
Я не пойму что вам нужно.

1. Если у вас должна быть одна f(), то тогда сотрите void f(){};, и после интерфейса класса определите её.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
namespace space
{
    class ok
    {
        friend void f() {}
    public:
        ok(){f();}
    };
}
int main() 
{
    space::ok a;
    return 0;
}
2. Если, нужно две (в пространстве space, и глобальная), то тогда нужно добавить определение второй (та которая friend).
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void f(){};
namespace space
{
    class ok
    {
        friend void f() {}
    public:
        ok(){f();}
    };
}
int main() 
{
    space::ok a;
    return 0;
}
mamucho666
1 / 1 / 0
Регистрация: 06.06.2012
Сообщений: 13
25.12.2012, 19:39  [ТС]     Дружественная функция, объявлённая ранее вне пространства имён класса -> error LNK2019 в Visual Studio 2012 #3
Мне нужно объяснить, почему "friend void f();" работает так, как будто ранее эта функция никогда не объявлялась.

То есть я ожидал, что "friend void f();" объявит ::f() дружественной, потому что не найдя в области "space", компилятор бы начал искать объявление в глобальной области.

А на деле происходит, что объявления f() в глобальной области не видно (или оно даже не ищется?) и получается, что f() помещается в область "space".

Или я могу поставить свой вопрос по другому: Почему, чтобы мой код корректно работал, нужно использовать "friend void ::f()".

Поиск объявления (в случае объявления дружественности) идёт только по области видимости, в которой расположено объявление класса?
Issues
429 / 364 / 37
Регистрация: 06.08.2012
Сообщений: 961
25.12.2012, 19:51     Дружественная функция, объявлённая ранее вне пространства имён класса -> error LNK2019 в Visual Studio 2012 #4
mamucho666,
допустим у вас есть две переменные х, одна локальная, вторая глобальная. Ну так вот сначала идёт всегда локальная, тоесть если вы напишите х = 10, то это означает, что локальная = 10, чтобы получить доступ к глобальной, с таким же именем (х) нужно указать глобальную область видимости ::х = 10.

С функциями в вашем примере так же.

Добавлено через 2 минуты
Но есть одно но.

Добавлено через 56 секунд
C++
1
friend void f();
это прототип, стало быть обьявление вы должны писать после.
mamucho666
1 / 1 / 0
Регистрация: 06.06.2012
Сообщений: 13
25.12.2012, 21:18  [ТС]     Дружественная функция, объявлённая ранее вне пространства имён класса -> error LNK2019 в Visual Studio 2012 #5
Это понятно, но продолжая пример с переменными, хочу заметить, что у меня нет локальных переменных.

На всю программу есть только одно объявление функции f() и оно в самой первой строке. Оно же глобальное. Где локальная функция?

P.S. Или само по себе объявление функции дружественной "friend void f();" и является её объявлением? В контексте моего кода локальным?
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11819 / 6798 / 769
Регистрация: 27.09.2012
Сообщений: 16,870
Записей в блоге: 2
Завершенные тесты: 1
25.12.2012, 22:38     Дружественная функция, объявлённая ранее вне пространства имён класса -> error LNK2019 в Visual Studio 2012 #6
Цитата Сообщение от mamucho666 Посмотреть сообщение
В итоге получаю:
Ошибка линковщика. У Вас нет реализации функции f() и линковщик не может её найти. Поэтому и выдает ошибку:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void f(){};
namespace space
{
    class ok
    {
        friend void f();
    public:
        ok(){f();}
    };
     void f(){}//////////////.........
}
int main() 
{
    space::ok a;
    return 0;
}
Yandex
Объявления
25.12.2012, 22:38     Дружественная функция, объявлённая ранее вне пространства имён класса -> error LNK2019 в Visual Studio 2012
Ответ Создать тему
Опции темы

Текущее время: 14:22. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru