gpt4 book ai didi

c++ - 在 C++ 中使用通用接口(interface)实现比较

转载 作者:太空狗 更新时间:2023-10-29 21:09:11 25 4
gpt4 key购买 nike

假设我正在开发一个处理 Item 类型项目的库。主要入口点是一个像这样的类:

class Worker
{
private:
SomeContainer _c;
public:
void add( const Item &i );
void doSomething();
};

doSomething() 方法查看添加的项目,比较它们等,并对它们做一些事情。所以 Item 类需要一个 operator==

现在,我想在不同的环境中使用这个库,并且在每个环境中 Item 类的实现是不同的。因此,Item需要一个虚拟比较函数:

class Item
{
protected:
virtual bool _equals( Item &other ) = 0;
public:
bool operator==( Item &other ) { return _equals( other ); };
};

并且每个环境都有自己的 Item 实现。该库只知道 Item 类,特定的项目类在使用该库的特定于平台的应用程序中定义和实现。在环境 A 中可能是:

class AItem: public Item
{
private:
bool _equals( Item &other );
std::string _member;
...
};

在环境B中:

class BItem: public Item
{
private:
bool _equals( Item &other );
int _member;
...
};

对于每个环境,现在最好的方法是什么来实现图书馆使用的比较? _equals是在Item类中指定的,所以其具体的item实现需要将other转换为自己的类型。

在给定的环境中,不会同时使用不同的项目类型,因此根据该假设,以下内容是安全的:

bool AItem::_equals( Item &other )
{
return this->_member == static_cast<AItem &>(other)._member;
}

但这似乎是一个令人讨厌的解决方案,因为它允许程序员使用库来实现一个新的环境,如果他向 worker 添加不同类型的项目,就会破坏事情。

我能想到的其他解决方案是:

  • 使用dynamic_cast
  • 通过向指示环境的基础 Item 类添加一个成员来实现我自己的 RTTI。然后可以在比较函数中使用它来查看 other 是否属于同一类型。不是很优雅。
  • 实现库中的所有类型,并在编译时根据#define 选择正确的类型。这意味着库本身必须针对每个环境进行扩展。
  • 使用模板化 worker。

但我觉得一定有更优雅的解决方案。也许是完全不同的东西。你会怎么做?

最佳答案

  • 如果 Worker 在 Item 上模板化而不是依赖继承不是更好吗?一般来说,值(value)语义(平等是值(value)语义的基础)不适用于继承。在您的具体示例中,如果 SomeContainer 确实复制了其中存储的内容,我也担心会被截断。

  • 如果你真的需要一个依赖于两个对象的动态类型的操作,你应该搜索“multiple dispatch”(或者看看“Modern C++ Design”,它有一章是关于这个主题的)。有几种已知的技术可以实现不同的权衡。最著名的一种通常与访问者模式相关联。最简单的变体取决于事先知道 Item 的所有后代。 (如果您查看访问者模式的描述,请考虑到该模式的两个层次结构对于您的应用程序来说是统一的)。

编辑:这里是一个例子的草图:

class ItemA;
class ItemB;

class Item
{
public:
virtual bool equal(Item const&) const = 0;
protected:
virtual bool doesEqual(ItemA const*) const { return false; }
virtual bool doesEqual(ItemB const*) const { return false; }
};

class ItemA: public Item
{
public:
virtual bool equal(Item const& other) const
{
return other.doesEqual(this);
}
protected:
virtual bool doesEqual(ItemA const* other) {
return do_the_check;
}
};

class ItemB: public Item
{
public:
virtual bool equal(Item const& other) const
{
return other.doesEqual(this);
}
protected:
virtual bool doesEqual(ItemB const* other) {
return do_the_check;
}
};

bool operator==(Item const& lhs, Item const& rhs)
{
return lhs.equal(rhs);
}

关于c++ - 在 C++ 中使用通用接口(interface)实现比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1184264/

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