По организации кода: 1 класс (MyClass) = MyClass.h + MyClass.cpp. friend классы и функции лучше не использовать.
Наследованием не увлекаться. Если у вашего класса ровно 1 наследник, то наследование скорее всего не нужно. Шаблонные классы тоже скорее всего не пригодятся.
Основной профит от класов -- инкапсуляция. Например вы создаете класс который должен качать что-то из интернета PackageUploader. Начинайте с его интерфейса (набор его public методов). Это то, что вам нужно от этого класса. Например он может скачать программу по имени и номеру версии:
/// Скачать программу по имени с заданной версией.
/// Возвращает путь до скачанного файла в локальном
std::filesystem::path downloadPackage(const std::string &name, const std::string &versionString);
Для того чтобы это сделать, ему потребуется информация о том, где нужно брать программу. Например можно в конструктор PackageUploader передать класс, который хранит такую информацию на диске или в реестре.
/// Конструктор PackageUploader.
/// Принимает PackageRegistry, который хранит информацию об адресах
/// на которых можно скачать различные программы.
PackageUploader(const PackageRegistry &packageRegistry);
Напишите несколько классов, которые вы бы хотели выделить и их интерфейсы без реализации. И я, или кто-то еще сможем что-то посоветовать.