具有不同参数的重载函数

问题描述 投票:1回答:3

希望您可以帮我解决这个问题。考虑以下类层次结构:

class Collider
{
  public:
  ... //Some functions that aren't worth mentioning. They all are abstract so the class is abstract.
}

class CircleCollider : public Collider
{
  private:
  vec2 pos_;
  float radius_;

  public:
  ... //The definition of the parent functions and constructor / destructor.
}

class RectCollider : public Collider
{
  private:
  vec2 pos_;
  vec2 size_;

  public:
  ... // Again, the definition of the parent functions and constructor / destructor.
}

在另一个类中,有一个指向父类的指针,该类根据枚举值创建两个子类之一的新实例,如下所示:

void SetCollisionType(ECollisionType Type)
{
  switch(Type)
  {
    case CIRCLE:
    {
       Collider* collider = new CircleCollider(pos, radius);
       break;
    }
    case RECTANGLE:
    { 
       Collider* collider = new RectCollider(pos, size);
       break;
    }
  }
}

[请注意,我已经简化了该函数,因此您可以了解我的代码的工作原理。现在,我要执行的功能是更新每个Child类的成员变量,即radiusCircleCollidersizeRectCollider。我想到了向Collider类添加功能:

virtual void UpdateCollider(float NewRadius, vec2 NewSize) = 0;

然后在每个子类中定义它。

   void CircleCollider::UpdateCollider(float NewRadius, vec2 NewSize)
   { 
     radius_ = NewRadius;
   }

   void RectCollider::UpdateCollider(float NewRadius, vec2 NewSize)
   {
     size_ = NewSize;
   }

我看到的问题是,CircleCollider中使用的定义将不使用NewSize参数,NewRadius中使用的定义也会发生同样的变化。但是,我无法想到另一种方法。您知道利用此代码中存在的层次结构和多态性的另一种方法吗?提前非常感谢您!

c++ polymorphism hierarchy
3个回答
0
投票

您可以使用基类函数,将指向Collider的指针作为输入参数。然后使用dynamic_cast确定Collider对象的类型并相应地更新参数。

这样的东西,

RectCollider

当然,您需要一些用于radius_和size_的访问器进行编译,否则,您需要将它们作为公共成员。


0
投票

如果您可以使用C ++ 17或更高版本,我建议使用void Collider::UpdateCollider(Collider *p, float NewRadius, vector NewSize) { if(CircleCollider *p_circle_collider = dynamic_cast<CircleCollider *>(p)) { // this is a CircleCollider object p_circle_collider->radius_ = NewRadius; } else if( RectCollider *p_rect_collider = dynamic_cast<RectCollider *>(p)) { // this is a RectCollider object p_rect_collider->size_ = NewSize; } }

当然是穷人的std::variant std::variant

std::variant

当然,如果您真的想使其可扩展用于其他用途,则您还可以使用would probably be a union


-3
投票

我建议为您的虚拟函数使用单个模板变量。例如(在Collider类中):

union UpdateArg {
    float NewRadius;
    vec2 NewSize;
};
//...
void RectCollider::UpdateCollider(UpdateArg NewSize) {
    //...
}

请记住,您还需要完全按照.h文件中的定义定义模板。我不认为在这种情况下,可以使用一串if / else语句来解决任何问题(std::any可能有效,但我不确定)。希望对您有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.