在 c++ 中抽象两个略有不同的函数的最佳方法是什么?
What is the best way to abstract two slightly different functions in c++?
假设我有一个类,它实现了任意数量的类似方法,相同的返回类型和相同的参数类型以保持简单。
页眉:
protected:
void MoveForward(float Magnitude);
void MoveRight(float Magnitude);
实现:
void MyCharacter::MoveForward(float Magnitude) {
AddMovementInput(GetActorForwardVector() * Magnitude);
}
void Myharacter::MoveRight(float Magnitude) {
AddMovementInput(GetActorRightVector() * Magnitude);
}
非常相似的方法,但仅在方法名称的方向(在本例中为向前和向右(以及其中一个内部函数的名称上有所不同。
在这里抽象通用结构的最佳方法是什么?
您可以通过多种方式做到这一点,我个人使用了一种类似于以下内容的方法:
enum class Direction { LEFT, RIGHT, TOP, BOTTOM };
class MyCharacter {
template<Direction DIR> Vector MyCharacter::getVector() const;
template<Direction DIR> void move() {
AddMovementInput(getVector<Dir>() * magnitude);
}
}
template<> Vector MyCharacter::getVector<Direction::LEFT>() const { ... }
template<> Vector MyCharacter::getVector<Direction::RIGHT>() const { ... }
当然,您可以在没有模板的情况下做同样的事情,但我想如果您特别需要它们,您知道自己在做什么。
请注意,您可以直接将该函数作为模板参数传递,但我发现它不太清楚,如下所示:
float GetActorForwardVector() { return 3.0f; }
class Foo
{
public:
template<float (*F)()> float move() { return F(); }
inline float moveLeft() { return move<GetActorForwardVector>(); }
};
int main()
{
Foo foo;
std::cout << foo.moveLeft();
}
老实说,你不应该在这个算法级别进行概括。你只需得到一个向量并用常量缩放它。如果你正在做一些更复杂的事情,那将是另一回事。我的第一个也是最重要的建议是让它保持这种状态。
其次,如果你坚持在这里泛化,它是(我假设GetXVector方法是类成员(:
class Foo
{
protected:
void MoveForward(float x) { Move(&Foo::GetActorForwardVector, x); }
void MoveRight(float x) { Move(&Foo::GetActorRightVector, x); }
private:
template<typename GetDirectionFunc>
void Move(GetDirectionFunc getDirection, float x)
{
AddMovementInput((this->*getDirection)() * x);
}
};
我更喜欢你的原始代码。
您可以使用标记调度。
使用实现特定行为的相同static
成员函数创建标记类:
namespace Direction {
struct Forward
{
static Vector actorVector() { return GetActorForwardVector(); }
};
struct Right
{
static Vector actorVector() { return GetActorRightVector(); }
};
} // namespace Direction
在您的类中,实现一个模板move
函数,该函数采用 Direction 类的实例,但不使用它。相反,它调用标记类的static
成员函数。
class MyCharacter
{
public:
template< typename Direction >
void move( const float magnitude, const Direction )
{
AddMovementInput( Direction::actorVector() * magnitude );
}
};
使用示例:
MyCharacter mc;
mc.move( 10.0, Direction::Forward() );
如果要创建更多方向,则只需要一个新的标记类来实现静态成员函数。
模板不是用来处理不同值(向前、向右(的,它们意味着处理不同的类型(整数、双精度(。 您可以将一个通用 Move 函数与参数一起使用:
void Move(int x, int y);
// Move forward
Move (0, 1);
// Move right
Move (1, 0);
可以使用函数指针在结构中组合移动方向和相应的函数:
struct MOVE_INFO
{
int x;
int y;
void (*GetVector)(void);
}
void Move(MOVE_INFO mv)
{
...
mv.GetVector();
...
}
main()
{
MOVE_INFO forward = {0, 1, SomeLib::GetForwardVector};
MOVE_INFO right = {1, 0, SomeLib::GetRightVector};
// Move Forward
Move(forward);
// Move Right
Move(right);
}
相关文章:
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 复制包含C++所有元素的对象!(构造函数和赋值,最佳实践?
- C++:将向量传递到构造函数以创建成员变量的最佳方法?
- C++ 将函数指针与最佳性能相结合
- 在指向现有内存地址的 hpp 文件中声明成员函数的最佳方法
- std::使用类成员函数创建线程 - 最佳实践
- 将(临时的?)std::string传递给使用它来构造一个接受副本的对象的函数的最佳方法是什么?
- 在 c++ 或 python 中生成一个体面的视差图以在 Raspberry Pi 上实现的最佳方法(算法或函数)是什么
- 将uint8_t*buffer和size_tbufferlen从C++传递到C中的API函数的最佳方式是什么
- 从类中的对象调用类中的函数的最佳方法
- 这是使用构造函数初始化数组对象的最佳方法吗?
- 最佳做法:在函数中频繁使用大时态缓冲区 (C++)
- 在 c++ 中抽象两个略有不同的函数的最佳方法是什么?
- C++最佳实践:接受uint8_t、uint16_t、uint32_t、浮点数的函数
- 使用 emplace_back 避免移动构造函数调用的最佳方法?
- 调用不属于基类的派生类函数的最佳方法是什么?
- C++最佳实践 - 函数类型别名 std::function<T> 或 T
- C++ std::string 中是否有任何函数可以计算两个字符串的相同起始字符的总数或任何最佳方法
- 从C 中的函数中动态分配的缓冲区返回的最佳模式是什么?
- 字符传递给其他函数最佳实践