Unreal Engine has a class called FVector
which is a somewhat simple three component float
vector.
One of the things that can be represented with that vector are coordinates. However, those coordinates can be in global space and local space.
There is a problem in the code base that I'm working on that it's not exactly clear which type of coordinate which functions take and it can be difficult to discern in what space a particular coordinate variable is when reading a random snippet of code.
I would like to have two types that behave the same way as FVector
that represent those two cases, but cannot interact with one another, except through a explicit conversion function.
This way I can ensure that functions that take coordinates are explicit in what type of coordinate they take and the wrong type of coordinate cannot be passed to them by accident. Also when doing calculations with the coordinates, this would ensure that you cannot do operations between the two different types on accident.
What would be the best approach to this without outright duplicating the whole FVector
class?
The solution should have minimal overhead and shouldn't make writing the code harder (when working with those types, users shouldn't really notice that they aren't FVectors
until they try to pass them to the wrong function or add to a FVector
). I'd like to avoid modifying the FVector
base class, but would be willing to do it as long as behavior of FVector
outside interacting with those types wouldn't change.
What would be the best approach to this without outright duplicating the whole
FVector
class?
You can provide a type aliases for the template class, which inherits from the FVector
, as follows:
namespace internal
{
// Main template class for coordinates
template<typename SpaceTag>
class TCoordinate final : public FVector
{
public:
using FVector::FVector; // Inherit constructors
// ... Add addtional FVector operations as needed
};
}
// Type aliases for cleaner usage
using FGlobalCoordinate = internal::TCoordinate<struct GlobalSpaceTag>;
using FLocalCoordinate = internal::TCoordinate<struct LocalSpaceTag>;
// Conversion functions
FLocalCoordinate GlobalToLocal(const FGlobalCoordinate& Global);
FGlobalCoordinate LocalToGlobal(const FLocalCoordinate& Local);
See a live demo
Keep in mind that FVector
might not have a virtual destructor(Most likely this would be the version OP is talking about), therefore assigning the allocated memory for the above two classes to FVector
wouldn't be a good idea. Read more here:
Is it okay to inherit implementation from STL containers, rather than delegate?
In that case, you have to use the FVector
should be a data member to the TCoordinate
class and delegate all the members required.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With