gpt4 book ai didi

c++ - 装饰器还是抽象基类?两者都不对

转载 作者:行者123 更新时间:2023-11-30 03:03:38 25 4
gpt4 key购买 nike

我正在编写一个接口(interface),它基本上有两个方法 next 尝试获取下一个值和 prev 返回上一个值。

struct foo
{
virtual boost::optional<int> next() = 0;
virtual int prev() = 0;
};

基本上首先调用next 就可以使用该接口(interface),如果调用失败,可以使用prev 获取之前的值。 prev 并不像这个例子中那么简单,prev 值应该发生一些其他的事情。 prev 方法对所有类的工作方式几乎相同,我想提供它的默认实现。

我必须有多种实现方法,但我都不喜欢:

第一种可能性是抽象基类而不是接口(interface)。

struct abstract_foo : public foo
{
int prev_;

virtual boost::optional<int> next()
{
boost::optional<int> val = do_next();
if(val)
prev_ = *val;
return val;
}

int prev()
{
return prev_;
}

virtual boost::optional<int> do_next() = 0;
};

但是,它破坏了接口(interface),现在要么必须记住调用 abstract_foo::next,要么被迫实现一个相当丑陋的 do_next

另一种方法是使用装饰器:

struct foo
{
virtual boost::optional<int> next() = 0;
virtual int prev()
{
throw not_implemented();
}
};

struct foo_decorator : public foo
{
std::unique_ptr<foo> foo_;
int prev_;

foo_decorator(std::unique_ptr<foo>&& foo)
: foo_(std::move(foo))
{
}

boost::optional<int> next()
{
boost::optional<int> val = foo_->next_value();
if(val)
prev_ = *val;
return val;
}

int prev()
{
return prev_;
}
};

在这里,not_implemented 只是为用户认为他们可以直接从基类使用 prev 的意外尖叫。

有没有人对好的设计有好的建议?或者我应该简单地使用某种辅助类来帮助在派生类中手动实现它?

最佳答案

您的第一个选项实际上接近首选方式,如下所示:

class foo
{
public:
boost::optional<int> next()
{
boost::optional<int> val = do_next();
if(val)
prev_ = val;
return val;
}

int prev()
{
return prev_;
}

private:
int prev_;
virtual boost::optional<int> do_next() = 0;
};

注意 next()prev() 是非虚拟的,而 do_next() 是私有(private)的。 Public non-virtual interface calls private virtual implementation .

关于c++ - 装饰器还是抽象基类?两者都不对,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9252897/

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