gpt4 book ai didi

c++ - 在没有指针的情况下在 C++ 中实现策略模式

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

我的目标是拥有 Strategy Pattern 的 C++ 实现无需手动分配内存。从概念上讲,我觉得在我给出的例子中没有必要这样做。此外,手动内存管理容易出错。请记住,我的示例只是一个 MWE,实际上所有对象都更加复杂,手动内存管理通常会引入错误。


在下面的示例中,类 Base 需要被赋予要构造的 Strategy,它将用于在其方法 getStrategyDecision 中生成输出()。当然,它不能被赋予一个Strategy,因为那个类是抽象的,所以这个参数必须是一个引用。由于我的上述原因,它不是一个指针。

以下代码可以编译,但因为在多个地方添加了const

class Strategy {
public:
virtual int decision() const = 0;
};

class AlwaysZero : public Strategy {
public:
int decision() const { return 0; }
};


class Base {
private:
Strategy const &strategy;
public:
Base(Strategy const &s) : strategy(s) {}

int getStrategyDecision() {
return strategy.decision();
}
};


class Main : public Base {
public:
Main() : Base(AlwaysZero()) {}
};


int main ()
{
Main invoker;
return invoker.getStrategyDecision();
}

如果删除 const 限定符,它将失败,因为在 Main 的构造函数中,将临时对象 AlwaysZero() 传递给引用Base 的构造函数的参数是非法的。

我能理解那个错误,但是

  1. 为什么当所有内容都是const 时它仍然有效?这似乎表明它应该在没有 const 的情况下同样有效,我只是遗漏了一些东西。
  2. 我什至不想要一个“临时”对象,我必须这样做的唯一原因是因为我不能传递 Strategy 本身,因为类是抽象的.

同样,我知道我可以通过使变量 strategy 成为指向 Strategy 的指针并将 new AlwaysZero() 传递给来解决这个问题Base 构造函数。如上所述,这是我不想要的


我的问题是双重的。首先,我想知道为什么我的示例在没有 const 的情况下无法编译。我想了解这里发生了什么。

其次,我想知道是否可以修改此示例,以便 strategy 不再是 const(并且它有效),但不使用任何类型的指针.只有当第二个问题的答案是“否”时,我才会开始寻找巧妙的方法来避免这个问题(例如评论中建议的智能指针)。

PS:我使用 g++ 作为编译器。这可能重要也可能不重要。

最佳答案

您的代码编译的原因是 const 引用可以延长临时对象的生命周期,但非 const 引用不会。参见 https://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/以获得详细的解释。

至于为什么 C++ 标准说非常量引用不会延长临时对象的生命周期。正如解释的那样 here ,非常量引用首先不能绑定(bind)到临时对象。参见 here举一个简单的例子来说明原因。

所以,您的技术应该没问题。但是如果你想要一些其他的选择......

策略模板

template<typename T>
class Base {
private:
T strategy;
public:
Base(const T& s) : strategy(s) {}

int getStrategyDecision() {
return strategy.decision();
}
};

class Main : public Base<AlwaysZero> {
public:
Main() : Base(AlwaysZero()) {}
};

非拥有指针

您可以使用指针而无需手动内存管理。只要它们是非拥有指针。

class Base {
private:
Strategy *strategy;
protected:
void setStrategy(Strategy& s) { strategy = &s; }
public:
int getStrategyDecision() {
return strategy->decision();
}
};

class Main : public Base {
AlwaysZero my_strategy;
public:
Main() { setStrategy(my_strategy); }
};

关于c++ - 在没有指针的情况下在 C++ 中实现策略模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43778197/

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