防止未经授权使用组件
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 不属于它的人。这个问题有很多解决方案,我需要一个高效实用的解决方案。这是我的:
如果客户端试图在不添加的情况下将组件函数分配给自己,则抛出异常;
创建一个系统,通过该系统可以识别 object 和组件,并且该组件会跟踪它所拥有的 object 以及 object让我们跟踪它拥有的组件。因为这是一个 many-to-many 关系,所以必须创建一个管理所有这些的中间 class;它还避免了循环 header 包含。
有一个函数不属于 object 只是 'deactivated'。这将需要使用像 'componentAdded' 这样的布尔值,并且所有函数都必须检查组件是否已添加,否则该函数将不会执行它应该执行的操作。
如果您有其他解决方案来防止未经授权使用组件,请分享它们,因为我很想向其他人学习他们如何 implemented/or 像我在这里所做的那样实施组件系统。
您无法阻止特定的 class 继承。这是一个全有或全无的命题:任何 class 都继承自基础或 none。
最好的办法就是缩小界面。例如,您可能希望使用 class Stationary_Object
或 Enemy_Object
来优化接口,而不是在函数中允许 Object
的后代。这允许您编写接受任何 Enemy_Object
而不会接受 Stationary_Object
的函数(如树或墙)。
编辑 1:与朋友作弊
您可以通过将成员声明为私有并使用 friend
class 授予对特定 classes 的访问权限来允许成员访问。问题是每当创建新类型的 friend 时,都需要修改带有数据的 class 。我相信这种 friend
ship 的使用违背了可重用性的目的。
编辑 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_Engine
和 Boat_Engine
。 Car
现在有一个 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 传递给任一函数。这些功能需要特定的引擎类型。
我正在构建一个组件系统,其中继承了抽象类型 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 不属于它的人。这个问题有很多解决方案,我需要一个高效实用的解决方案。这是我的:
如果客户端试图在不添加的情况下将组件函数分配给自己,则抛出异常;
创建一个系统,通过该系统可以识别 object 和组件,并且该组件会跟踪它所拥有的 object 以及 object让我们跟踪它拥有的组件。因为这是一个 many-to-many 关系,所以必须创建一个管理所有这些的中间 class;它还避免了循环 header 包含。
有一个函数不属于 object 只是 'deactivated'。这将需要使用像 'componentAdded' 这样的布尔值,并且所有函数都必须检查组件是否已添加,否则该函数将不会执行它应该执行的操作。
如果您有其他解决方案来防止未经授权使用组件,请分享它们,因为我很想向其他人学习他们如何 implemented/or 像我在这里所做的那样实施组件系统。
您无法阻止特定的 class 继承。这是一个全有或全无的命题:任何 class 都继承自基础或 none。
最好的办法就是缩小界面。例如,您可能希望使用 class Stationary_Object
或 Enemy_Object
来优化接口,而不是在函数中允许 Object
的后代。这允许您编写接受任何 Enemy_Object
而不会接受 Stationary_Object
的函数(如树或墙)。
编辑 1:与朋友作弊
您可以通过将成员声明为私有并使用 friend
class 授予对特定 classes 的访问权限来允许成员访问。问题是每当创建新类型的 friend 时,都需要修改带有数据的 class 。我相信这种 friend
ship 的使用违背了可重用性的目的。
编辑 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_Engine
和 Boat_Engine
。 Car
现在有一个 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 传递给任一函数。这些功能需要特定的引擎类型。