防止未经授权使用组件

时间:2015-04-29 00:47:29

标签: c++ oop sfml

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

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,每当我调用玩家的更新功能时,我也会调用对象的更新功能。这应该是自动化的,但将来会发生变化。真正的问题是:

pPlayer仍然可以访问pMovable的速度,即使它尚未添加pMovable作为组件。这是有问题的,因为这意味着任何人都可以简单地从pMovable获取速度,然后将其插入到对象中,而无需添加pMovable作为其组件的一部分。现在,倾向于发生的事情是,由于没有可移动的组件来调节它,因此运动变得不受管理。我将这个组件的未经授权使用称为术语,并且我想开发一种方法,通过该方法,组件可以“拒绝”将其功能用于不属于它的对象。这个问题有很多解决方案,我需要一个有效且实用的解决方案。这是我的:

  1. 如果客户端尝试将组件功能分配给自己而不添加它,则抛出异常;

  2. 创建一个系统,通过该系统识别对象和组件,组件跟踪它所拥有的对象,并且对象跟踪它拥有的组件。因为这是一个多对多的关系,所以必须创建一个管理所有这些的中间类;它还避免了圆形标题包含。

  3. 让一个函数不是一个对象的一部分,只是'停用'。这将需要使用类似'componentAdded'的布尔值,并且所有函数都必须检查是否添加了组件,否则函数将不会执行应该执行的操作。

  4. 如果您有其他解决方案可以防止未经授权使用组件,请分享它们,因为我希望向其他人学习如何实现/或实现组件系统。

1 个答案:

答案 0 :(得分:0)

您无法阻止特定类继承。它是一个全有或全无的命题:任何类都继承自基类或没有。

你可以期待的最好的是缩小界面。例如,您可能希望使用类ObjectStationary_Object来优化接口,而不是在函数中允许Enemy_Object的后代。这使您可以编写任意Enemy_Object并且不会采用Stationary_Object(如树或墙)的函数。

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

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

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

在上面的示例中,Engine类有两个特化:Car_EngineBoat_EngineCar现在有Car_Engine成员,BoatBoat_Engine成员。

现在可以创建功能以在特殊引擎上运行:

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

fix_car_engine现在只适用于汽车发动机。您可以说它适用于任何具有Car Engine的类(只要您传递Car Engine成员)。同样,fix_boat_engine功能仅适用于船用发动机。

鉴于:

class Rocket_Engine : public Engine;

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