无法访问Friend类的私有构造函数

Cannot access private constructors of a Friend class

本文关键字:构造函数 访问 Friend      更新时间:2023-10-16

我有以下两个类:

struct Entity 
{
    unsigned id;
    Entity(unsigned id);
    Entity();
};
class EntityManager
{
public:
    Entity create();
    ...
private:
    Entity make_entity(unsigned index, unsigned generation);
};

这目前运行良好。问题在于封装。我不想允许直接创建类Entity

因此,我的目标是使Entity的构造函数私有化。然后我可以(根据我的理解)通过使Entity成为EntityManagerfriend来保持EntityManager中的功能。

因此,做出改变的结果是:

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);
};

这打破了密码。我得到的错误是:

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);
                     ^

实现文件如下所示:

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(..., ...);
}

有没有什么明显的东西让我遗漏了?我还尝试将实现中的Entity(id)调用为Entity::Entity(id),但随后我得到了另一个错误:

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);

您向后拥有friend声明。您需要在Entity结构中有此行:

friend class EntityManager;

友元声明需要进入Entity类,而不是EntityManager类。否则,任何任意类都可以通过在声明中放置friend class X来访问另一个类的私有数据。想要共享其私有数据的类必须明确声明。

尝试以下

struct Entity;
class EntityManager
{
public:
    Entity create();
private:
    Entity make_entity(unsigned index, unsigned generation);
};
struct Entity 
{
private:
    unsigned id;
    Entity(unsigned id);
    Entity();
    friend Entity EntityManager::make_entity(unsigned index, unsigned generation);
};

您的friend声明是向后的。交友类包含可由交友类使用的私有(和/或受保护)成员。

struct Entity 
{
    unsigned id;
private:
    Entity(unsigned id);
    Entity();
    friend class EntityManager;
};