C++策略模式

发布于 2024-12-03 09:00:42 字数 353 浏览 0 评论 0原文

过去,我将策略模式解释为一种机制,允许函数/类的用户为该函数/类提供自己的功能。

我一直被教导实现该模式的方法是将函数指针放入类/函数中并在内部调用它们,从而允许程序员提供自己的“策略”,这些策略将由这些函数和对象在内部使用。

最近环顾四周,我发现策略模式似乎总是通过使用继承层次结构来解释/定义,如下所示:

策略模式实现

这是意见/实现的差异,还是传递的函数指针实际上不是策略模式的变体?我最感兴趣,所以当我评论或解释我的代码时我不会让人们感到困惑:)

In the past, I have seen the strategy pattern explained as a mechanism which allows the user of a function/class to provide their own functionality for that function/class.

I had always been taught that the way to implement the pattern was by taking function pointers into your classes/functions and calling them internally, thus allowing the programmer to provide their own "strategy" which would be used internally by those functions and objects.

Looking around more recently, I see that the strategy pattern always seems to be explained/defined through the use of an inheritance hierarchy like so:

Strategy pattern implementation

is this a difference of opinion/implementation, or is the function pointer passing not really a variation of the strategy pattern? I'm mostly interested so I don't confuse people when I comment or explain my code :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

悲歌长辞 2024-12-10 09:00:42

您只需在没有函数指针的语言中使用继承(例如:Java)。

就我个人而言,我更喜欢 std::function 而不是原始函数指针,因为它接受更广泛的参数,并允许您维护策略对象中的状态。

此外,如果您已经知道编译时的策略,您甚至可以使用模板,从而节省函数指针和 std::function 对象的空间和运行时开销。

You simply have to use inheritance in languages without function pointers (read: Java).

Personally, I would prefer std::function over raw function pointers, because it accepts a wider range of arguments and allows you to maintain state in the strategy object.

Also, if you already know the strategy at compile-time, you can even use templates and thus save both the space and runtime overhead of function pointers and std::function objects.

夜光 2024-12-10 09:00:42

在我看来,使用函数指针实现策略模式是在不支持 OOP 的语言(例如 C)中完成的。

在支持OOP的语言中,最好使用类来实现:继承、虚函数(即运行时多态性)、接口等。通常,这是运行时策略模式,这意味着,您只需在运行时切换到其他策略模式即可更改程序的行为。

在 C++ 中,还有一种编译时策略模式,通常称为基于策略的设计

无论如何,类可以维护状态,而函数指针则不能。这是使用类的最大优点。

In my opinion, implementation of strategy pattern using function pointers is done in languages which don't have support for OOP (such as C).

In languages which support OOP, its better implemented using classes : inheritance, virtual functions (i.e runtime polymorphism), interface, and so on. Usually, this is runtime strategy pattern which means, you can change the behavior of the program just by switching to other strategy pattern, at runtime.

In C++, there is also a compile-time strategy pattern, commonly known as policy-based design.

In any case, classes can maintain states, while function pointers cannot. That is the biggest advantage in using classes.

关于从前 2024-12-10 09:00:42

使用函数指针来实现策略是基于继承的版本的退化情况。如您所知,该模式的基本核心是能够在运行时提供或修改某个进程的组件。该组件可以是一个函数,也可以是一个对象。如果策略由多个位组成,那么基于继承的版本确实更好,因为一个对象可以将多个方法打包在一起;如果只有一块,那么函数指针也差不多。

Using function pointers to implement strategy is sort of a degenerate case of the inheritance based version. The essential kernel of the pattern is, as you know, being able to supply or modify a component of some process at runtime. That component can be a function, or it can be an object. If the strategy consists of several bits, an inheritance-based version is really nicer, as an object can package several methods together; if there's just one piece, then function pointers are pretty much as good.

¢蛋碎的人ぎ生 2024-12-10 09:00:42

IMO,策略模式可以使用以下方式实现:

  • 模板和编译时常量表达式(早期绑定,实际上可能不称为策略模式)。
  • 虚函数机制(是的,通过将不同的派生类分配给引用/指针)。
  • 函数指针
  • 指向类的成员(方法)的指针。
  • 使用 std::function 并使用 lambda。

IMO, strategy pattern can be implemented using:

  • Templates and compile-time constant expressions (Early-bound, may not be actually called as strategy-pattern).
  • Virtual function mechanism (Yes, by assigning different derived classes to a reference/pointer).
  • Function pointers
  • Pointer-to-members (methods) of a class.
  • Using std::function, and using lambdas.
指尖上的星空 2024-12-10 09:00:42

接口对象可以具有状态,因此可以维护成员变量。函数指针不能。

Interface objects can have state, and therefore maintain member variables. Function pointers cannot.

喜爱皱眉﹌ 2024-12-10 09:00:42

这是 C++ 策略模式的实用代码。我希望纯虚函数的使用(而不是 Java 中的接口)是不言自明的。

#include <iostream>
#include <fstream>
#include <string.h>

using namespace std;

class Strategy;

class TestBed{
  public:
    TestBed(){
        myStrategy = NULL;
    }
    void setBehavior(int type);
    Strategy *myStrategy;
};

class Strategy{
  public:
    void performBehavior(){
       behave();
    }
  private:
    virtual void behave() = 0;
};

class behaviorOne: public Strategy{
  private:
    void behave(){
        cout << "left strategy" << endl;
    }
};

class behaviorTwo: public Strategy{
  private:
    void behave(){
        cout << "right strategy" << endl;
    }
};

class behaviorThree: public Strategy{
  private:
    void behave(){
        cout << "center strategy" << endl;
    }
};

void TestBed::setBehavior(int type){  
  delete myStrategy;
  if (type == 0)
    myStrategy = new behaviorOne();
  else if (type == 1)
    myStrategy = new behaviorTwo();
  else if (type == 2)
    myStrategy = new behaviorThree();
}

int main(){
  TestBed test;
  int answer;  
  while(1){
     cout << "Exit(other) Left(0) Right(1) Center(2): ";
     cin >> answer;
     if(answer > 2) break;
     test.setBehavior(answer);
     test.myStrategy->performBehavior();
  }   
  return 0;
}

This is a practical code for strategy pattern in c++. I hope pure virtual funcation usage (instead of interface in Java) is self explanatory.

#include <iostream>
#include <fstream>
#include <string.h>

using namespace std;

class Strategy;

class TestBed{
  public:
    TestBed(){
        myStrategy = NULL;
    }
    void setBehavior(int type);
    Strategy *myStrategy;
};

class Strategy{
  public:
    void performBehavior(){
       behave();
    }
  private:
    virtual void behave() = 0;
};

class behaviorOne: public Strategy{
  private:
    void behave(){
        cout << "left strategy" << endl;
    }
};

class behaviorTwo: public Strategy{
  private:
    void behave(){
        cout << "right strategy" << endl;
    }
};

class behaviorThree: public Strategy{
  private:
    void behave(){
        cout << "center strategy" << endl;
    }
};

void TestBed::setBehavior(int type){  
  delete myStrategy;
  if (type == 0)
    myStrategy = new behaviorOne();
  else if (type == 1)
    myStrategy = new behaviorTwo();
  else if (type == 2)
    myStrategy = new behaviorThree();
}

int main(){
  TestBed test;
  int answer;  
  while(1){
     cout << "Exit(other) Left(0) Right(1) Center(2): ";
     cin >> answer;
     if(answer > 2) break;
     test.setBehavior(answer);
     test.myStrategy->performBehavior();
  }   
  return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文