希望您可以帮我解决这个问题。考虑以下类层次结构:
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类的成员变量,即radius
的CircleCollider
和size
的RectCollider
。我想到了向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
中使用的定义也会发生同样的变化。但是,我无法想到另一种方法。您知道利用此代码中存在的层次结构和多态性的另一种方法吗?提前非常感谢您!
您可以使用基类函数,将指向Collider的指针作为输入参数。然后使用dynamic_cast确定Collider对象的类型并相应地更新参数。
这样的东西,
RectCollider
当然,您需要一些用于radius_和size_的访问器进行编译,否则,您需要将它们作为公共成员。
如果您可以使用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。
我建议为您的虚拟函数使用单个模板变量。例如(在Collider类中):
union UpdateArg {
float NewRadius;
vec2 NewSize;
};
//...
void RectCollider::UpdateCollider(UpdateArg NewSize) {
//...
}
请记住,您还需要完全按照.h文件中的定义定义模板。我不认为在这种情况下,可以使用一串if / else语句来解决任何问题(std::any
可能有效,但我不确定)。希望对您有帮助!