Это звучит как очень очевидный вопрос, но я ничего не могу найти в Интернете. У меня есть класс other
, который обрабатывает message
в одном из своих методов. Для этого он должен получить доступ к частному члену данных сообщения, следовательно, он должен быть его другом. Но я не могу заставить его скомпилировать. Независимо от порядка объявления, он всегда жалуется на неполные типы. Как еще я мог бы добиться такого?
#include <cstdio>
struct other;
class message
{
friend auto other::handle_message(message) -> void;
int private_ = 10;
};
struct other
{
auto handle_message(message msg) -> void {
printf("Private part of msg is %d!\n", msg.private_);
}
};
int main() {}
Первое и главное решение — не требовать дружбы.
Зачем вам нужен приватный доступ к внутренностям другого класса? Обычно в этом нет необходимости при правильном проектировании. Мне это редко нужно при перегрузке некоторых (потоковых) операторов. Во всех остальных случаях, вообще или через определенные интерфейсы (абстрактные базовые классы), к которым может привести другой класс (сделать доступ явным для конкретной цели, а не все или ничего друга)
Либо message
необходимо объявить other
(или его функцию-член) как friend
, либо message
необходимо предоставить public
геттер, который извлекает значение private_
. Суть private
доступа в том, что конструктор класса message
запрещает доступ не-друзьям. Если бы класс other
мог в одностороннем порядке отменить это и притвориться дружбой, то не было бы смысла в контроле доступа.
Пример доступа через определенный интерфейс: onlinegdb.com/zpPysvzqP
Вам нужно следующее
class message;
struct other
{
auto handle_message(message msg) -> void;
};
/* or just
struct other
{
auto handle_message( class message msg) -> void;
};
*/
class message
{
friend auto other::handle_message(message) -> void;
int private_ = 10;
};
auto other::handle_message(message msg) -> void {
printf("Private part of msg is %d!\n", msg.private_);
}
То есть класс other
должен быть определен до класса message
, а его функция-член handle_message
должна быть определена после определения класса message
.
Вот демонстрационная программа.
#include <cstdlib>
class message;
struct other
{
auto handle_message( message msg ) -> void;
};
class message
{
friend auto other::handle_message( message ) -> void;
int private_ = 10;
};
auto other::handle_message( message msg ) -> void {
std::printf( "Private part of msg is %d!\n", msg.private_ );
}
int main()
{
other().handle_message( message() );
}
Вывод программы
Private part of msg is 10!
Ах, глупо, я не разделил определение и объявление для handle_message, спасибо.
@glades Вовсе нет. Если ваша проблема решена, выберите ответ как лучший ответ, чтобы закрыть вопрос. :)
Очевидно, что класс other должен быть определен перед сообщением класса.