I am learning C++ and game design using comp4300. In the assignment 2 of the class, the instructor uses a friend
class to access the entity
class, but I am not able to do that and I get an error:
entity::entity cannot access private member declared in class “Entity”
Entity.h
#pragma once
#include "component.h"
#include <memory>
#include <string>
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);
public:
std::shared_ptr<CTransform> cTransform;
std::shared_ptr<CShape> cShape;
std::shared_ptr<CCollision> cCollision;
std::shared_ptr<CScore> cScore;
std::shared_ptr<CLifespan> cLifespan;
std::shared_ptr<CInput> cInput;
bool isActive() const;
const std::string& tag() const;
const size_t id() const;
void destroy();
};
EntityManager.h
#pragma once
#include "entity.h"
#include <vector>
#include <map>
typedef std::vector<std::shared_ptr<Entity> > EntityVec;
typedef std::map<std::string, EntityVec> EntityMap;
class EntityManager
{
EntityVec m_entities;
EntityMap m_entityMap;
EntityVec m_toAdd;
size_t m_totalEntities{ 0 };
public:
EntityManager();
std::shared_ptr<Entity> addEntity(const std::string& tag);
void update();
EntityVec& getEntities();
EntityVec& getEntities(std::string& tag);
};
EntityManager.cpp
#include "entitymanager.h"
EntityManager::EntityManager()
:m_totalEntities(0)
{
}
std::shared_ptr<Entity> EntityManager::addEntity(const std::string& tag)
{
auto e = std::make_shared<Entity>(m_totalEntities++, tag);
m_toAdd.push_back(e);
return e;
}
I tried everything but it’s just not working.
1
EntityManager
is not the one trying to directly access the private Entity
constructor, which is why making it a friend
doesn’t work. std::make_shared()
(or more accurately, an internal type that represents the control block of std::shared_ptr
) is the one trying to access the Entity
constructor, so that type is what needs to be made a friend
instead.
Otherwise, you should change your Entity
class so it can create instances of itself (ie, via a static
method that returns a shared_ptr
) so it can use its own private constructor, instead of letting EntityManager
create them.
1