Если вам нужно реализовать форматирование файла и сохранить / загрузить из вне класса, то вы можете сделать это только с данными, которые общедоступны. Если при сохранении / загрузке необходимо работать с непубличными данными, если при перезагрузке класса невозможно восстановить исходные непубличные данные из общедоступных данных, то в этом должен участвовать либо сам класс, либо друзья этого класса. На самом деле не существует способа обойти это.
Максимум, что вы можете сделать, - это упростить написание новых типов с шаблоном друга. Например:
class DataType
{
...
private:
template<typename format> friend void SaveFile<format>(const DataType *, ofstream&);
};
Тип шаблона format
будет пустым типом. Так что если у вас есть formatA и formatB, у вас будут пустые структуры:
struct FormatA {};
struct FormatB {};
Затем все, что вам нужно сделать, это написать специализированные версии SaveFile для этих форматов:
template<> void SaveFile<FormatA>(const DataType *, ofstream&);
template<> void SaveFile<FormatB>(const DataType *, ofstream&);
Они автоматически станут друзьями DataType.