gpt4 book ai didi

c++ - 由于多重继承的重复变量

转载 作者:太空狗 更新时间:2023-10-29 20:04:19 27 4
gpt4 key购买 nike

我有 3 个类 ABC,声明为

class A {
int varA;
};
class B {
int varB;
};
class C : public A, public B {
void setVar(int var) {
varA = var;
varB = var; // <- duplicate
}
};

现在 C 类将有 2 个变量 varAvarB。在我的例子中,两个变量具有相同的含义(例如物理对象的位置),因此必须始终相同,因为成员函数只会对它们自己的变量进行计算。


我考虑过为AB 添加父类,但同样的问题仍然存在:

class Parent {
public:
int var;
};

class A : public Parent {};
class B : public Parent {};

class C : public A, public B {
void setVar(int v) {
A::var = v;
B::var = v; // <- duplicate
// or
var = v; // <- compiler error: Ambiguous call
}
};

有人知道这个问题的优雅解决方案吗?


编辑:上下文

AB 分别是 PhysicsCollidablePhysics 类使对象具有加速度、速度和位置等变量。并包含几个成员函数,用于根据耗时计算下一个位置。另一个类 Collidable 使一个对象能够与其他对象交互(碰撞),定义它们在发生碰撞时的行为,同时还检查它们是否确实发生了碰撞。此类具有位置和边界框等变量。

重叠变量因此是位置,因为两个类都需要它,彼此独立。 Collidable 类不需要从 Physics 继承,因为例如墙不需要加速度和/或速度等变量,因为它是静态的。

我想为 C 使用继承,因为它将是一个是一个物理对象和是一个可碰撞对象的对象。 has-a 关系似乎不合适,因此我选择了继承而不是组合。

最佳答案

要解决您所写的问题,您可以使用虚拟父级,以便在子类中将其作为一个实例共享:

class Parent {
public:
int var;
};

class A : public virtual Parent {}; // ** Note I added virtual here
class B : public virtual Parent {}; // ** Note I added virtual here

class C : public A, public B {
void setVar(int v) {
var = v; // No longer ambiguous.
}
};

但这听起来像是一种可以使用另一种外观的设计。为什么两个不相关的类都具有相同的数据(在您的原始设计中)?稍微考虑一下这些事情,也许您会想到一个替代设计(基类中的抽象接口(interface),使用模板算法将类绑定(bind)在一起的机制等)。或者,如果您提供有关类关系的更多信息,我们可以提供 C++ 惯用的解决方案。

编辑:

我认为我更喜欢的另一个想法是将位置的状态与物理和可碰撞对象分开,增加一个间接级别。所以 physics 和 collidable 都有指向外部位置状态对象的指针。由于它是外部的,因此两者都将引用并能够改变相同的共享状态。所需的所有权将决定所使用的指针类型。

粗略的草图可能是这样的:

class Position {};

class A
{
public:
explicit A(const shared_ptr<Position>& pos) : pos_(pos) {}

private:
shared_ptr<Position> pos_;
};

class B
{
public:
explicit B(const shared_ptr<Position>& pos) : pos_(pos) {}

private:
shared_ptr<Position> pos_;
};

class C : public A, public B
{
public:
explicit C(const shared_ptr<Position>& pos) : A(pos), B(pos) {}
};

int main()
{
shared_ptr<Position> pos = make_shared<Position>();

C object_of_type_C(pos);
}

最后请注意,is-a 虽然是一个有用的指南,但不应该真正确定您何时继承。它的真正含义是您想要获取一个 C 并透明地将其用裁剪理或可碰撞对象,而相关代码实际上并不知道它是一个 C。如果这代表您的需要,那么这就是对您的设计的真正考验(请参阅 Liskov 替换原则)。

关于c++ - 由于多重继承的重复变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20617461/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com