我创建了一个抽象类,它只有一组纯虚拟方法。有3个不同的类具有这些方法的具体实现。
现在,在编写了上述结构之后,我发现派生类中的一些方法具有相同的实现。所以,我为这些函数转移到我的基类的逻辑,并使它们虚拟而不是纯虚拟。现在,实现不需要在派生类中重复。这编译并执行正常。
我的基类是纯虚方法和虚方法的混合,是否遵循这样的结构是一种很好的设计方法?
答案 0 :(得分:5)
它绝对没问题,虽然似乎已经出现了一个模式,你可以将所有和仅你的纯虚函数放在一个类中更像是一个界面。
然后,您将定义一个实现" common"该接口的一部分,并让你的3个类继承自该类。
随着时间的推移,似乎这适用于更具可扩展性且更易于维护的代码。
Java,出于兴趣,几乎强迫使用这种模式。
答案 1 :(得分:1)
显然,它取决于类之间的关系。换句话说,它是一种设计或实现选择(即由您自己决定,只要您能够合理地证明它合理)。从技术上讲,没有什么能阻止类混合使用虚拟,纯虚拟,非虚拟和静态成员函数。
如果两个派生类重写了一个继承的虚函数并以相同的方式实现它,那么 - 是的 - 我会认真考虑将该函数提供给基类。但是,我会问更多的问题 - 例如,所有派生类是否有意义默认为该函数的实现。从代码重用的角度来看,这样的事情可能有意义。从设计的角度来看,它可能不会。
也就是说,如果将函数的特定实现视为“默认”是有意义的(即所有派生类默认使用它,除非它们覆盖该函数),那么将该定义放在一个中是没有害处的。基类。
作为一个粗略的例子,你的建议没有意义,请考虑这个
class Aircraft
{
public:
virtual void Manoeuvre() = 0;
};
class Hornet : public Aircraft // F/A-18 hornet fighter aircraft
{
public:
void Manoeuvre();
};
class Tomcat : public Aircraft // F-14 tomcat fighter aircraft
{
public:
void Manoeuvre();
};
让我们说,由于我们的建模的保真度,两个派生类都具有相同的Manoeuvre()
功能 - 它们都是超音速战斗机(所以可能采用类似的机动风格,虽然参数化程度不同) 。但是,这还不足以将他们的Manoeuvre()
功能移到基类,因为有些飞机不是超音速战斗机,例如
class Hercules : public Aircraft // C-130 hercules cargo plan
{
public:
void Manoeuvre();
};
在这种情况下,Hercules
继承超音速战斗机的机动能力是没有意义的,反之亦然。因此,由Aircraft
类提供它是没有意义的。
在这种情况下,我可能会考虑引入中间类,例如Fighter
(可能是Hornet
和Tomcat
的共同基础,但不是Hercules
)和 - 如果我试图代表多种类型的货机 - 可能CargoPlane
是这些货机的共同基础。然后,Fighter
和CargoPlane
可能来自Aircraft
,但Aircraft
不提供仅对某些机型有意义的功能。
附带注释:虽然有些人声称没有,但C ++中没有任何内容可以防止纯虚函数出现定义(实现)。意思是函数必须被派生类覆盖,但是基类提供了一个默认定义(可以由派生类中的函数显式调用)。
答案 2 :(得分:0)
是的,没关系。但是:如果这些都是您拥有的所有类,则无需进行基类实现virtual
。