У меня есть класс, и я пытаюсь создать функцию друга для работы с данными этого класса.
Вот пример того, что я пытаюсь сделать:
// test.hpp
class test
{
public:
friend void friendly_function();
private:
int data;
};
void test::friendly_function()
{
data = 0;
}
Однако компилятор выдает ошибку: test.hpp:23:34: error: no ‘void test::friendly_function()’ member function declared in class ‘test’
Я знаю, что могу объявить операторы следующим образом:
class test
{
public:
friend const bool operator<(const test& _lhs, const test& _rhs);
private:
int data;
};
const bool test::operator<(const test& _lhs, const test& _rhs)
{
return (_lhs.data < _rhs.data);
}
Так почему я не могу сделать это с friendly_function
? Разрешены ли функции-друзья только как операторы?
На самом деле мне удалось выяснить проблему до того, как я разместил этот вопрос, поэтому казалось разумным дать ответ, так как другие люди могут найти его полезным в будущем. Я также установил ответ на «сообщество вики», чтобы другие люди могли улучшить его, если они хотят.
Проблема в том, что функции-друзья не являются членами класса, и поэтому должны быть закодированы без test::
спецификатор, так как они не являются членами class test
,
Декларация friend void friendly_function();
должен быть внутри тестового класса, так как это говорит компилятору, что friendly_function()
разрешен доступ к частным членам test
,
поскольку friendly_function()
не является членом class test
было бы неплохо собрать весь этот код в пространстве имен, которое сгруппирует все функции и классы в одном логическом блоке.
namespace test_ns {
class test
{
public:
friend void friendly_function(test &_t);
friend bool operator<(const test& _lhs, const test& _rhs);
private:
int data;
}; // class test
void friendly_function(test &_t)
{
_t.data = 0;
}
bool operator<(const test& _lhs, const test& _rhs)
{
return _lhs.data < _rhs.data;
}
} // namespace test_ns
Это должно решить проблему. Функции-друзья довольно тонкие в том смысле, что они могут выглядеть как функции-члены, но на самом деле это не так!
Других решений пока нет …