防止未经授权使用组件

Preventing unauthorised use of components

我正在构建一个组件系统,其中继承了抽象类型 Component 来制作组件。到目前为止,我有可绘制的、物理的、可移动的和其他组件。一切似乎都很顺利,在 Game class 中我执行了以下操作:

void Game::init()
{
    pPlayer->addComponent(pMovable);
}

void Game::processEvents()
{
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
        pMovable->moveUp(2.f);

    // etc..

    pPlayer->setVelocity(pMovable->getVelocity());
}

void Game::update()
{
    pPlayer->update(0);
}

void Game::play()
{
    while (pWindow->isOpen())
    {
        // ...
        processEvents();
    }
}

到目前为止,组件系统真的很基础和简单。播放器是 Object 类型,每当我调用播放器的更新函数时,我也会调用 Object 的更新函数。这确实应该是自动化的,但将来会改变。真正的问题是什么:

pPlayer 仍然可以访问 pMovable 的速度 ,即使它没有添加 pMovable 作为组件。这是有问题的,因为这意味着任何人都可以简单地从 pMovable 中获取速度,然后将其插入他们的 object 而无需添加 pMovable 作为其组件的一部分。现在,往往会发生的是运动变得不受管理,因为没有可移动的组件来调节它。我将这种未经授权的使用称为组件,并且我想开发一种方法,组件可以通过这种方式 'deny' 将其功能使用给 object 不属于它的人。这个问题有很多解决方案,我需要一个高效实用的解决方案。这是我的:

  1. 如果客户端试图在不添加的情况下将组件函数分配给自己,则抛出异常;

  2. 创建一个系统,通过该系统可以识别 object 和组件,并且该组件会跟踪它所拥有的 object 以及 object让我们跟踪它拥有的组件。因为这是一个 many-to-many 关系,所以必须创建一个管理所有这些的中间 class;它还避免了循环 header 包含。

  3. 有一个函数不属于 object 只是 'deactivated'。这将需要使用像 'componentAdded' 这样的布尔值,并且所有函数都必须检查组件是否已添加,否则该函数将不会执行它应该执行的操作。

如果您有其他解决方案来防止未经授权使用组件,请分享它们,因为我很想向其他人学习他们如何 implemented/or 像我在这里所做的那样实施组件系统。

您无法阻止特定的 class 继承。这是一个全有或全无的命题:任何 class 都继承自基础或 none。

最好的办法就是缩小界面。例如,您可能希望使用 class Stationary_ObjectEnemy_Object 来优化接口,而不是在函数中允许 Object 的后代。这允许您编写接受任何 Enemy_Object 而不会接受 Stationary_Object 的函数(如树或墙)。

编辑 1:与朋友作弊
您可以通过将成员声明为私有并使用 friend class 授予对特定 classes 的访问权限来允许成员访问。问题是每当创建新类型的 friend 时,都需要修改带有数据的 class 。我相信这种 friendship 的使用违背了可重用性的目的。

编辑 2:检测所有权
假设我们有三个 classes:

class Engine;

class Car
{
  Engine car_engine;
};

class Boat
{
  Engine boat_engine;
};

还有一个函数:

void Fix_Car_Engine(Engine& e)
{
}

C++ 中没有方法让 Fix_Car_Engine 知道它是在修理汽车引擎还是船引擎。该函数只知道它已被赋予一个通用引擎来修复(或者它只知道变量的通用引擎内容)。

可以通过改进或缩小界面来缓解此问题:

class Car_Engine : public Engine;
class Boat_Engine : public Engine;

class Car
{
  Car_Engine diesel_engine;
};

class Boat
{
  Boat_Engine propellor_engine;
};

在上面的示例中,引擎 class 有两个特化:Car_EngineBoat_EngineCar 现在有一个 Car_Engine 成员,Boat 有一个 Boat_Engine

现在可以创建函数以在特殊引擎上运行:

void fix_boat_engine(Boat_Engine& be);
void fix_car_engine(Car_Engine& ce);

fix_car_engine 现在仅适用于汽车引擎。您可以说它适用于任何具有 Car Engine 的 class(只要您通过了 Car Engine 成员)。同样,fix_boat_engine 函数仅在船用发动机上运行。

鉴于:

class Rocket_Engine : public Engine;

此外,此特化可防止将 Rocket_Engine 传递给任一函数。这些功能需要特定的引擎类型。