Search code examples
c++friend

Cannot access private constructors of a Friend class


I have the following two classes:

struct Entity 
{
    unsigned id;
    Entity(unsigned id);
    Entity();
};

class EntityManager
{
public:
    Entity create();
    ...

private:
    Entity make_entity(unsigned index, unsigned generation);
};

This works fine at the moment. The problem is the encapsulation. I dont want to allow the direct creating of the class Entity.

Because of that, my goal is to make the constructors of Entityprivate. Then I could (from what I understand) mantain functionality in EntityManager by making Entity a friend of EntityManager.

So making the changes this would be the result:

struct Entity 
{
    unsigned id;
private:
    Entity(unsigned id);
    Entity();
};

class EntityManager
{
    friend struct Entity;
public:
    Entity create();

private:
    Entity make_entity(unsigned index, unsigned generation);
};

That breaks the code. The error that I get is this one:

entity_manager.cpp: In member function ‘Entity EntityManager::make_entity(unsigned int, unsigned int)’:
entity_manager.cpp:12:1: error: ‘Entity::Entity(unsigned int)’ is private
 Entity::Entity(unsigned id) : id(id) {}
 ^
entity_manager.cpp:19:21: error: within this context
     return Entity(id);
                     ^

The implementation file is like this one:

Entity::Entity() : id(0) {}
Entity::Entity(unsigned id) : id(id) {}

Entity EntityManager::make_entity(unsigned idx, unsigned  generation)
{
    unsigned id = 0;
    id = ...
    return Entity(id);
}

Entity EntityManager::create()
{
    ...
    return make_entity(..., ...);
}

Is there anything obvious that I am missing here? I also tried calling Entity(id) on the implementation as Entity::Entity(id), but I then get another error:

entity_manager.cpp: In member function ‘Entity EntityManager::make_entity(unsigned int, unsigned int)’:
entity_manager.cpp:19:29: error: cannot call constructor ‘Entity::Entity’ directly [-fpermissive]
     return Entity::Entity(id);

                             ^
entity_manager.cpp:19:29: note: for a function-style cast, remove the redundant ‘::Entity’
entity_manager.cpp:12:1: error: ‘Entity::Entity(unsigned int)’ is private
 Entity::Entity(unsigned id) : id(id) {}
 ^
entity_manager.cpp:19:29: error: within this context
     return Entity::Entity(id);

Solution

  • You have the friend declaration backwards. You need to have this line in the Entity struct:

    friend class EntityManager;