gpt4 book ai didi

c++ - 从接口(interface)的父接口(interface)在哪里实现功能?

转载 作者:行者123 更新时间:2023-11-27 22:33:19 25 4
gpt4 key购买 nike

我被要求实现一个接口(interface),我想知道尽可能分解代码的最佳策略是什么。

这是接口(interface)定义(我不应该更改它):

#include <string>

class BaseIf
{
public:
virtual ~BaseIf() {}

virtual std::string getName() = 0;
};

class IntIf : public BaseIf
{
public:
virtual ~IntIf() {}

virtual int getValue() = 0;
};

class FloatIf : public BaseIf
{
public:
virtual ~FloatIf() {}

virtual float getValue() = 0;
};

我将以 IntImpl(实现 IntIf)和 FloatImpl(实现 FloatIf)结束。但是我想知道我应该把这两个类共有的任何代码放在哪里(比如 name 属性管理或 BaseIf 所需的任何其他东西,这实际上比这个 MCVE)。

如果我用通用代码创建 BaseImpl(实现 BaseIfgetName 函数),并且有 IntImpl 派生自它(和 IntIf),那么我还需要在其中实现 getName,因为它被报告为未实现。而且我还获得了 BaseIf 的双重继承...

我想知道 Pimpl 模式是否有帮助,然后 IntImpl 将有一个 BaseImpl 对象作为属性(并且仅派生自 IntIf),但是,我又需要在 IntImpl 中实现 getName 以“转发”对 BaseImpl 属性的调用。因此,由于 BaseIf 实际上有许多虚函数,因此维护起来会非常痛苦。

是否没有聪明的解决方案/模式可以在一个公共(public)地方只实现一次getName?或者只是界面不好,应该重新设计?

最佳答案

这是虚拟继承的主要用例。

尽管存在多重继承和虚拟继承的种种污名,但当我们的接口(interface)(无数据成员)被虚拟继承时,并没有特别的问题。这是要点:

class BaseIf
{
public:
virtual ~BaseIf() {}

virtual std::string getName() = 0;
};

class IntIf : public virtual BaseIf
{
public:
virtual ~IntIf() {}

virtual int getValue() = 0;
};

class BaseImpl : public virtual BaseIf
{
public:
std::string getName () override { return "whoa dude"; }
};

class IntImpl : public virtual IntIf, public BaseImpl
{
public:
int getValue() override { return 42; }
};

full demo

对于更深的层次结构,可能还必须虚拟继承实现类,这不是很方便,但仍然可行。

实现的虚拟继承的替代方法是将实现分层为“构建 block ”层和最后一层。构建 block 是独立的,不继承其他构建 block 。 (它们可能继承接口(interface))。 final 类继承构建 block ,但不继承其他 final 类。

class BaseBlock : public virtual BaseIf
{
public:
std::string getName () override { return "whoa dude"; }
};

class IntBlock : public virtual IntIf
{
public:
int getValue() override { return 42; }
};

class BaseImpl : public BaseBlock {};

class IntImpl : public BaseBlock, public IntBlock {};

full demo

如果层次结构中没有虚拟继承,则确实需要对接口(interface)进行更改。然而,这些更改是透明的(无需更改客户端代码,只需重新编译即可)并且无论如何都可能是有益的。

如果没有虚拟继承,人们将不得不求助于大量样板文件。

class BaseBlock // no base class!
{
public:
virtual std::string getName () { return "whoa dude"; }
};

class BaseImpl : public BaseIf, public BaseBlock
{
public:
// oops, getName would be ambiguous here, need boplerplate
std::string getName () override { return BaseBlock::getName(); }
};

关于c++ - 从接口(interface)的父接口(interface)在哪里实现功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58240721/

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