Другой вариант - использовать идиому PIMPL , где частью реализации структуры является указатель на другой тип. Большинство пользователей класса просто включают обычный заголовочный файл, где реализация представляет собой непрозрачный указатель. Классы, которым требуется доступ к частным данным, могут включать заголовок, определяющий другой тип, и использовать интерфейс, который он предоставляет.
Это общий шаблон для программистов на Си, которым нужна функциональность, похожая на друга. По моему мнению, он также более тесно связан с размышлением о разделении интересов (обычно хороший принцип проектирования, который приводит к многоразовому, ортогональному коду), а не об инкапсуляции (специфичная для ОО методика, которая полезна для реализации разделения интересов, но также часто используется неправильно). усложнять вещи).
Он имеет преимущество перед другом в том, что он вообще не связывает друга с другом. Некоторые люди могут утверждать, что это недостаток, поскольку теперь любой может «подружиться» с вашим классом. Я думаю, что это необоснованный страх, так как вы все еще делаете отношения явными (включая заголовок). Если вы боитесь этого, вы боитесь вашей (или вашей коллеги) способности принимать умные архитектурные решения. Но если вы не можете принять эти решения должным образом позже, почему вы доверяете себе friend
сейчас?
Это имеет недостаток затрат времени выполнения. Хранение данных в указателе приводит к ухудшению когерентности кэша и увеличению количества выделений, а также для его очистки необходим деструктор.