在C++中,要实现一个连续使用->
操作符来构建行为树的功能,你可以通过返回一个指向自身的指针或者引用来实现链式调用下面是一个使用链式调用的行为树构建例子:
首先,我们定义行为树的各个组件,包括Node
基类、Selector
选择器、Sequence
序列器、Condition
条件节点和Action
行为节点。
#include <iostream>
#include <functional>
#include <memory>
// 行为树节点基类
class Node {
public:
virtual ~Node() = default;
virtual bool run() = 0;
// 返回指向自身的指针,用于链式调用
virtual Node* self() { return this; }
};
// 智能指针类型别名
using NodePtr = std::shared_ptr<Node>;
// 选择器节点
class Selector : public Node {
private:
std::vector<NodePtr> children;
public:
// 添加子节点并返回自身指针
Selector& addChild(NodePtr child) {
children.push_back(child);
return *this;
}
bool run() override {
for (const auto& child : children) {
if (child->run()) {
return true;
}
}
return false;
}
// 返回指向自身的指针,用于链式调用
Node* self() override { return this; }
};
// 序列器节点
class Sequence : public Node {
private:
std::vector<NodePtr> children;
public:
// 添加子节点并返回自身指针
Sequence& addChild(NodePtr child) {
children.push_back(child);
return *this;
}
bool run() override {
for (const auto& child : children) {
if (!child->run()) {
return false;
}
}
return true;
}
// 返回指向自身的指针,用于链式调用
Node* self() override { return this; }
};
// 条件节点
class Condition : public Node {
private:
std::function<bool()> condition;
public:
// 构造函数接受一个返回bool值的lambda表达式
Condition(std::function<bool()> conditionFunc) : condition(conditionFunc) {}
bool run() override {
return condition();
}
// 返回指向自身的指针,用于链式调用
Node* self() override { return this; }
};
// 行为节点
class Action : public Node {
private:
std::function<void()> action;
public:
// 构造函数接受一个无返回值的lambda表达式
Action(std::function<void()> actionFunc) : action(actionFunc) {}
bool run() override {
action();
return true;
}
// 返回指向自身的指针,用于链式调用
Node* self() override { return this; }
};
// 构建行为树的辅助函数
NodePtr makeSelector() { return std::make_shared<Selector>(); }
NodePtr makeSequence() { return std::make_shared<Sequence>(); }
NodePtr makeCondition(std::function<bool()> condition) { return std::make_shared<Condition>(condition); }
NodePtr makeAction(std::function<void()> action) { return std::make_shared<Action>(action); }
int main() {
// 使用链式调用构建行为树
auto root = makeSelector()
->addChild(makeCondition([]() { return false; }))
->addChild(makeSequence()
->addChild(makeCondition([]() { return true; }))
->addChild(makeAction([]() { std::cout << "Action performed!" << std::endl; }))
);
// 运行行为树
bool success = root->run();
return 0;
}
在这个例子中,Node
基类提供了self()
方法,该方法返回指向当前节点的指针,这使得Selector
和Sequence
类可以返回自身指针来实现链式调用。每个节点类型都重载了addChild
方法来添加子节点,并返回*this
以支持链式调用。makeSelector
、makeSequence
、makeCondition
和makeAction
是辅助函数,用于创建特定类型的节点并初始化它们。
现在,你可以使用->
操作符来连续构建行为树了。在main
函数中,我们创建了一个选择器节点