使用friend类仍无法访问private Entity类的问题求助
无法通过友元类EntityManager访问Entity私有构造函数的问题解决
错误原因
你遇到的编译错误核心在于:std::make_shared并非Entity类的友元。尽管EntityManager被声明为Entity的友元,拥有调用其私有构造函数的权限,但std::make_shared会直接尝试调用Entity的私有构造函数来分配内存,它没有这个访问权限,因此编译器报错。
解决方案
方案1:改用std::shared_ptr直接构造(简单直接)
修改EntityManager.cpp中的addEntity函数,跳过std::make_shared,直接通过new创建Entity实例,再传递给std::shared_ptr的构造函数:
std::shared_ptr<Entity> EntityManager::addEntity(const std::string& tag) { std::shared_ptr<Entity> e(new Entity(m_totalEntities++, tag)); m_toAdd.push_back(e); return e; }
此方法中,EntityManager作为友元直接调用Entity的私有构造函数创建对象,std::shared_ptr仅负责接管对象所有权,无需访问构造函数,完美解决权限问题。
方案2:保留std::make_shared的封装性实现(推荐)
如果想保留std::make_shared的内存优化优势,可在Entity类中添加私有静态创建函数,由EntityManager调用:
- 修改
Entity.h,添加私有静态创建函数:
class Entity { friend class EntityManager; private: bool m_active = true; size_t m_id = 0; std::string m_tag = "Default"; Entity(const size_t id, const std::string& tag); // 私有静态创建函数,仅类内部/友元可调用 static std::shared_ptr<Entity> create(size_t id, const std::string& tag) { return std::make_shared<Entity>(id, tag); } public: // ... 原有公共成员 };
- 修改
EntityManager.cpp的addEntity函数:
std::shared_ptr<Entity> EntityManager::addEntity(const std::string& tag) { auto e = Entity::create(m_totalEntities++, tag); m_toAdd.push_back(e); return e; }
这种方法既保留了std::make_shared的内存效率,又维持了Entity类的封装性,是最优解。
方案3:为std::make_shared添加友元(不推荐)
若强行想直接使用std::make_shared,可在Entity类中为其添加友元声明,但这会扩大私有构造函数的访问范围,破坏封装性,不建议使用:
class Entity { friend class EntityManager; // 添加友元声明,允许std::make_shared访问私有构造 template<typename T, typename... Args> friend std::shared_ptr<T> std::make_shared(Args&&... args); private: // ... 原有私有成员 };
额外检查
确保Entity.h中的friend class EntityManager;声明有效——友元声明仅需类名,无需提前完整定义EntityManager,当前代码的头文件包含逻辑是正确的,无需调整。
内容的提问来源于stack exchange,提问作者blob blob
相关产品推荐
相关产品推荐

