ИМХО, почти никогда.
«Друг» часто используется для нарушения инкапсуляции в том смысле, что он может позволить внешнему объекту получить доступ к частным данным вашего класса. Вы почти никогда не хотите этого делать - часто лучше / безопаснее предоставлять «полуприватные» данные через общедоступные средства доступа (которые могут проверять достоверность), чем предоставлять конфиденциальную информацию другому классу (который может взломать все вокруг вас).
Однако иногда у вас будет пара / группа очень тесно связанных классов, в которых имеет смысл хранить их как отдельные классы, но им нужен низкоуровневый доступ к данным, которые на самом деле не должны передаваться всему миру. Здесь можно использовать «друга» - с осторожностью.
Обычно старайтесь ограничить область действия друзей (например, методы друзей, а не классы друзей), чтобы минимизировать области, в которых разрешен прямой доступ к частным данным. Сохраняйте это как можно более простым - помните, что другой программист, читающий ваш код, может подумать, что «частные» означают, что данные действительно являются частными, и их могут споткнуть друзья. Кроме того, чем больше друзей вы используете, тем более тесными и сложными в поддержании будет ваш дизайн. Они могут быть полезны, но убедитесь, что у вас есть хорошее обоснование для каждого использования.