Я новичек в С++, объясните пожалуйста, почему не отрабатывает дружественная функция в main? Имеется:
class myClass {
private:
int i,j;
public:
myClass();
virtual ~myClass();
friend void myFunc();
};
В main() такой код:
#include "myClass.h"
int main(int argc, char *argv[]) {
myClass a;
myFunc();
return EXIT_SUCCESS;
}
В результате ошибка:
'myFunc' was not declared in this scope
Дико извиняюсь, заранее спасибо за помощь!
Компилятор действительно не видит объявление функции, если она не объявлена вне класса, и не имеет место зависящий от аргумента поиск имени (ADL - Argument-Dependent name Lookup).
Поэтому объявите дружественную функцию также после определения класса.
class myClass {
private:
int i,j;
public:
myClass();
virtual ~myClass();
friend void myFunc();
};
void myFunc();
Сравните данные две демонстрационные программы.
#include <iostream>
class myClass {
private:
int i,j;
public:
myClass(){}
virtual ~myClass(){}
friend void myFunc() { std::cout << "Hi, I'm friend!" << std::endl; }
};
//void myFunc();
//^^^^^^^^^^^^^^
int main()
{
myFunc();
return 0;
}
и
#include <iostream>
class myClass {
private:
int i,j;
public:
myClass(){}
virtual ~myClass(){}
friend void myFunc() { std::cout << "Hi, I'm friend!" << std::endl; }
};
void myFunc();
//^^^^^^^^^^^^
int main()
{
myFunc();
return 0;
}
В первом случае возникнет ошибка компиляции, указывающая на то, что имя myFunc
не объявлено. Во втором же случае программа успешно скомпилируется и выведет на консоль текст
Hi, I'm friend!
В первом случае когда компилятор встречает имя myFunc
, то он ищет его в глобальном пространстве имен и не находит. Поэтому выдает диагностическое сообщение, аналогично показанном вами
'myFunc' was not declared in this scope
Если бы дружественная функция, объявленная в классе, имела аргумент, который имеет тип класса, то компилятор мог бы найти эту функцию, используя зависящий от аргумента поиск имени (ADL). Например,
#include <iostream>
class myClass {
private:
int i,j;
public:
myClass() : i( 10 ), j( 20 ){}
virtual ~myClass(){}
friend void myFunc( const myClass &c )
{
std::cout << "Hi, I'm friend!" << std::endl;
std::cout << "You have i = " << c.i << " and j = " << c.j << std::endl;
}
};
int main()
{
myClass c;
myFunc( c );
return 0;
}
Данная программа успешно скомпилируется и выведет на консоль
Hi, I'm friend!
You have i = 10 and j = 20
Так как дружественная функция имеет параметр типа const myClass &
, то, используя ADL, компилятор будет искать объявление дружественной функции также в классе myClass
.
Зависящий от аргумента поиск имени (ADL) можно отключить, если заключить имя функции в скобки. Твк, например, ниже-приведенная программа не будет компилироваться в виду того, что имя функции заключено в круглые скобки, и ADL не будет применен к поиску имени функции.
#include <iostream>
class myClass {
private:
int i,j;
public:
myClass() : i( 10 ), j( 20 ){}
virtual ~myClass(){}
friend void myFunc( const myClass &c )
{
std::cout << "Hi, I'm friend!" << std::endl;
std::cout << "You have i = " << c.i << " and j = " << c.j << std::endl;
}
};
int main()
{
myClass c;
( myFunc )( c );
return 0;
}
Перевод документов на английский язык: Важность и ключевые аспекты
Какие существуют виды рекламных бордов и как выбрать подходящий?
Консольное приложениеЕсть цикл, в нем по очереди вызываются 3 метода класса
Изучаю тему наследования по практикуму учебника 2010 годаТам есть пример, который я взял для изучения вопроса наследования, где используется...
Делаю всё по книге "Создание сетевых приложений в среде Linux: Руководство разработчика"Не компилируется