Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
bambique
1 / 1 / 3
Регистрация: 02.04.2015
Сообщений: 169
#1

Не вызывается дружественная функция - C++

31.10.2015, 14:57. Просмотров 258. Ответов 9
Метки нет (Все метки)

Создал класс, есть дружественная функция:
C++
1
2
3
4
5
6
7
8
9
int NOD(int a,int b)
{
    while(b)
    {
        a%=b;
        std::swap(a,b);
    }
    return a;
}
Не могу вызвать ее в конструкторе:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Drobi::Drobi(int a,int b)
{
    int temp;
    temp= NOD(a,b);
    if (temp == 1)
    {
        numerator = a;
        denomirator = b;
    }
    else
    {
        numerator = a/temp;
        denomirator = b/temp;
    }
}
Ошибка: 'NOD' was not declared in this scope
Прототип указал с ключевым словом friend вроде все нормально, не понимаю в чем проблема
http://www.cyberforum.ru/cpp-beginners/thread187012.html
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
31.10.2015, 14:57
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Не вызывается дружественная функция (C++):

Дружественная функция
#include <iostream> #include <math.h> using namespace std; class massiv {...

Дружественная функция
Хочу сделать вычисление площади как дружественную функцию, начал описывать,...

Дружественная функция
описать классы автомобиль и маршрут. Использовать дружественную функцию...

Дружественная 2-м классам функция.
Код программы: #include <iostream.h> class matrix; class vector{ int...

Дружественная функция. Графы
Здравствуйте! Задача такая: Пересечением двух графов называется граф, все...

9
DrOffset
7517 / 4513 / 1097
Регистрация: 30.01.2014
Сообщений: 7,362
31.10.2015, 15:07 #2
Цитата Сообщение от bambique Посмотреть сообщение
Прототип указал с ключевым словом friend
Судя по телу функции, ей вообще не надо быть friend.
Цитата Сообщение от bambique Посмотреть сообщение
в чем проблема
Наверное в том, что слишком мало кода ты нам показываешь.

На всякий случай:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Drobi
{
    friend int NOD(int, int);
public:
    Drobi(int a, int b);
};
 
int NOD(int a,int b)
{
    while(b)
    {
        a%=b;
        std::swap(a,b);
    }
    return a;
}
 
Drobi::Drobi(int a, int b)
{
    int temp = NOD(a, b);
 
    //......
}
0
bambique
1 / 1 / 3
Регистрация: 02.04.2015
Сообщений: 169
31.10.2015, 15:27  [ТС] #3
Цитата Сообщение от DrOffset Посмотреть сообщение
Наверное в том, что слишком мало кода ты нам показываешь.
У меня функция была в public, поместил в private, но ничего не изменилось.
Описание класса:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
namespace Drobik
{
class Drobi
{
private:
    int numerator;
    int denomirator;
    friend int NOD(int a,int b);
public:
    Drobi();
    Drobi(int,int);
    int Show_numerator() const;
    int Show_denomirator() const;
    Drobi operator*(Drobi const &d) const;
    Drobi operator/(Drobi const &d) const;
    friend std::ostream& operator<<(std::ostream& os,Drobi const &d);
};
}
Описание методов и т.д:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
namespace Drobik
{
 
Drobi::Drobi(int a,int b)
{    
    int temp= NOD(a,b);
    ....
}
int NOD(int a,int b)
{
    while(b)
    {
        a%=b;
        std::swap(a,b);
    }
    return a;
}
....
}
0
DrOffset
7517 / 4513 / 1097
Регистрация: 30.01.2014
Сообщений: 7,362
31.10.2015, 15:34 #4
Лучший ответ Сообщение было отмечено bambique как решение

Решение

bambique, напиши так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
namespace Drobik
{
int NOD(int a,int b);
 
class Drobi
{
private:
    int numerator;
    int denomirator;
    friend int NOD(int a,int b);
public:
    Drobi();
    Drobi(int,int);
    int Show_numerator() const;
    int Show_denomirator() const;
    Drobi operator*(Drobi const &d) const;
    Drobi operator/(Drobi const &d) const;
    friend std::ostream& operator<<(std::ostream& os,Drobi const &d);
};
}
1
bambique
1 / 1 / 3
Регистрация: 02.04.2015
Сообщений: 169
31.10.2015, 15:39  [ТС] #5
Цитата Сообщение от DrOffset Посмотреть сообщение
bambique, напиши так
Заработало спасибо, можете обьяснить почему именно так?
0
DrOffset
7517 / 4513 / 1097
Регистрация: 30.01.2014
Сообщений: 7,362
31.10.2015, 16:04 #6
Цитата Сообщение от bambique Посмотреть сообщение
можете обьяснить почему именно так?
По стандарту.
7.3.1.2/3
The name of the friend is not found by unqualified lookup (3.4.1) or by qualified lookup (3.4.3) until a matching declaration is provided in that namespace scope (either before or after the class definition granting friendship).
bambique, вот еще, с примером:
11.3/11
For a friend class declaration, if there is no prior declaration, the class that is specified belongs to the innermost enclosing non-class scope, but if it is subsequently referenced, its name is not found by name lookup until a matching declaration is provided in the innermost enclosing nonclass scope.
Пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class X;
void a();
void f() {
  class Y;
  extern void b();
  class A {
  friend class X;  // OK, but X is a local class, not ::X
  friend class Y;  // OK
  friend class Z;  // OK, introduces local class Z.
  friend void a(); // error, ::a is not considered
  friend void b(); // OK
  friend void c(); // error
  };
  X *px;           // OK, but ::X is found
  Z *pz;           // error, no Z is found
}
0
bambique
1 / 1 / 3
Регистрация: 02.04.2015
Сообщений: 169
31.10.2015, 18:06  [ТС] #7
Цитата Сообщение от DrOffset Посмотреть сообщение
For a friend class declaration, if there is no prior declaration, the class that is specified belongs to the innermost enclosing non-class scope, but if it is subsequently referenced, its name is not found by name lookup until a matching declaration is provided in the innermost enclosing nonclass scope.
Не могу полностью все перевести, но как я понял, компилятор просто не видит функцию NOD так как она определена после конструктора и надо указать прототип, для того чтобы компилятор мог ссылаться на нее, верно? И не понял почему в 10 строчке примера ошибка.

Добавлено через 10 минут
Обьясните по простому, сложный английский для меня.
0
hoggy
Заблокирован
31.10.2015, 18:29 #8
Цитата Сообщение от bambique Посмотреть сообщение
Обьясните по простому, сложный английский для меня.
может это вам поможет:
http://www.cyberforum.ru/cpp/thread1370987.html
0
DrOffset
7517 / 4513 / 1097
Регистрация: 30.01.2014
Сообщений: 7,362
31.10.2015, 20:42 #9
Цитата Сообщение от bambique Посмотреть сообщение
И не понял почему в 10 строчке примера ошибка
на самом деле я зря процитировал второй фрагмент, т.к. он касается локальных классов, а там требования строже. Но смысл, конечно, тот же.
Как было сказано в цитате, впервые определенная френд-декларация предполагает, что имя является членом наиболее вложенного неклассового пространства имен. Т.е. имя "а" расценивается, как принадлежащее пространству имен функции f(). Но функции такой (a) там нет, поэтому ошибка. Вот, например, какую диагностику выдаст на этот пример clang:
error: no matching function 'a' found in local scope; did you mean '::a'?

О таком запрете явно сказано:
If a friend declaration appears in a local class (9.8) and the name specified is an unqualified name, a prior
declaration is looked up without considering scopes that are outside the innermost enclosing non-class scope.
For a friend function declaration, if there is no prior declaration, the program is ill-formed.
Цитата Сообщение от bambique Посмотреть сообщение
но как я понял, компилятор просто не видит функцию NOD так как она определена после конструктора и надо указать прототип, для того чтобы компилятор мог ссылаться на нее, верно?
Да, он не видит функцию, потому что впервые (no prior declaration) объявленная функция (как friend) не рассматривается при поиске имен, пока ее имя не будет объявлено в том же пространстве имен, что и класс (innermost enclosing non-class scope). Т.е. в твоем случае - в Drobik.
C++
1
2
3
4
5
6
7
8
9
10
11
class X
{
    friend class C;
    
    friend int foo();
        
    void f() {
         C * p = 0; // error, класс C не существовал ранее, а френд-объявление не вносит имя С в поиск имен
         foo(); // error, тоже самое
    }
};
Одной лишь friend-декларации недостаточно для осуществления поиска имен.
1
bambique
1 / 1 / 3
Регистрация: 02.04.2015
Сообщений: 169
31.10.2015, 23:05  [ТС] #10
Цитата Сообщение от DrOffset Посмотреть сообщение
Одной лишь friend-декларации недостаточно для осуществления поиска имен.
Огромное спасибо за объяснение.
0
31.10.2015, 23:05
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.10.2015, 23:05
Привет! Вот еще темы с решениями:

Дружественная функция класса
Проблема в том что дружественная функция класа механик в класе car (friend void...

базовый,дочерний , дружественная функция
Базовый класс в нем будет массив имен из 10 элементов , конструктор должен сам...

Классы, конструктор, дружественная функция
Условие программы Описать структуру Комплексное число , и написать функцию,...

Дружественная функция подсчета площадей
В общем простенькую программу для подсчета площадей написал, а вот как...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru