#pragma once #include "ExpresssionNode.h" #include "component.hpp" #include "Registry.h" #include "Context.h" #include <vector> #include <memory> class AndNode : public ExpressionNode { public: explicit AndNode(std::vector<std::unique_ptr<ExpressionNode>> children); void execute(Context& ctx) override; private: std::vector<std::unique_ptr<ExpressionNode>> children_; bool getOutputValue(Context& ctx) { try { return ctx.get("output") == "true"; } catch (const std::exception&) { return false; } } class ContextSaver { public: ContextSaver(Context& ctx) : ctx_(ctx) { try { savedOutput_ = ctx.get("output"); hasSavedOutput_ = true; } catch (const std::exception&) { hasSavedOutput_ = false; } } ~ContextSaver() { if (hasSavedOutput_) { ctx_.set("output", savedOutput_); } else { try { //ctx_.ContextMap.erase("output"); } catch (...) {} } } private: Context& ctx_; std::string savedOutput_; bool hasSavedOutput_; }; }; #include "AndNode.h" AndNode::AndNode(std::vector<std::unique_ptr<ExpressionNode>> children) : children_(std::move(children)){} void AndNode::execute(Context& ctx) { bool result = true; std::lock_guard<std::mutex> lock(ctx.mtx); for (auto& child : children_) { ContextSaver saver(ctx); child->execute(ctx); bool childResult = getOutputValue(ctx); if (!childResult) { result = false; break; } } ctx.set("output", result ? "true" : "false"); } #include "Parser.h" #include <algorithm> #include <stdexcept> #include <sstream> #include <iostream> #include"SingleNode.h" #include"Context.h" #include"IfNode.h" #include"ThenNode.h" #include"WhenNode.h" #include"AndNode.h" #include"OrNode.h" #include"NotNode.h" using namespace std; unique_ptr<ExpressionNode> Parser::parse(const string& expr) { string cleaned = trim(expr); // 安全地移除外层括号 if (!cleaned.empty() && cleaned[0] == '(' && cleaned[cleaned.size() - 1] == ')') { cleaned = cleaned.substr(1, cleaned.size() - 2); cleaned = trim(cleaned); } return parseExpression(cleaned); } unique_ptr<ExpressionNode> Parser::parseSingleNode(const string& expr) { if (expr.find("THEN(") != 0 && expr.find("IF(") != 0 && expr.find("WHEN(") != 0 && expr.find("AND(") != 0 && expr.find("OR(") != 0 && expr.find("NOT(") != 0) { return make_unique<SingleNode>(expr); } return parseExpression(expr); } unique_ptr<ExpressionNode> Parser::parseIfExpression(const string& expr) { auto parts = splitComponents(expr); if (parts.size() < 2 || parts.size() > 3) { throw runtime_error("IF expression requires 2 or 3 arguments"); } auto conditionNode = parseLogicalExpression(parts[0]); auto thenNode = parseExpression(parts[1]); unique_ptr<ExpressionNode> elseNode = nullptr; if (parts.size() == 3) { elseNode = parseExpression(parts[2]); } return make_unique<IfNode>( move(conditionNode), move(thenNode), move(elseNode) ); } unique_ptr<ExpressionNode> Parser::parseThenExpression(const string& expr) { auto parts = splitComponents(expr); vector<unique_ptr<ExpressionNode>> children; for (const auto& part : parts) { children.push_back(parseExpression(trim(part))); } return make_unique<ThenNode>(move(children)); } unique_ptr<ExpressionNode> Parser::parseWhenExpression(const string& expr) { auto parts = splitComponents(expr); vector<unique_ptr<ExpressionNode>> children; for (const auto& part : parts) { children.push_back(parseExpression(trim(part))); } return make_unique<WhenNode>(move(children)); } vector<string> Parser::splitComponents(const string& expr) { vector<string> parts; // 添加空表达式检查 if (expr.empty()) return parts; int bracketCount = 0; size_t start = 0; for (size_t i = 0; i < expr.size(); ++i) { char c = expr[i]; if (c == '(') { bracketCount++; } else if (c == ')') { bracketCount--; } else if (c == ',' && bracketCount == 0) { string part = expr.substr(start, i - start); parts.push_back(trim(part)); start = i + 1; } } // 处理最后一个参数(确保不包含空字符串) if (start < expr.size()) { string lastPart = trim(expr.substr(start)); if (!lastPart.empty()) { // 添加空检查 parts.push_back(lastPart); } } return parts; } unique_ptr<ExpressionNode> Parser::parseExpression(const string& expr) { try { string trimmed = trim(expr); if (trimmed.empty()) { throw runtime_error("Empty expression"); } if (startsWith(trimmed, "THEN(")) { return parseThenExpression(trimmed.substr(5, trimmed.size() - 6)); } if (startsWith(trimmed, "IF(")) { return parseIfExpression(trimmed.substr(3, trimmed.size() - 4)); } if (startsWith(trimmed, "WHEN(")) { return parseWhenExpression(trimmed.substr(5, trimmed.size() - 6)); } if (startsWith(trimmed, "PAR(")) { return parseWhenExpression(trimmed.substr(4, trimmed.size() - 5)); } if (startsWith(trimmed, "AND(")) { return parseAndExpression(trimmed.substr(4, trimmed.size() - 5)); } if (startsWith(trimmed, "OR(")) { return parseOrExpression(trimmed.substr(3, trimmed.size() - 4)); } if (startsWith(trimmed, "NOT(")) { return parseNotExpression(trimmed.substr(4, trimmed.size() - 5)); } return parseSingleNode(trimmed); } catch (const exception& e) { cerr << "Parse EL error: " << e.what() << endl; throw; } } unique_ptr<ExpressionNode> Parser::parseLogicalExpression(const string& expr) { string trimmed = trim(expr); if (startsWith(trimmed, "AND(")) { return parseAndExpression(trimmed.substr(4, trimmed.size() - 5)); } if (startsWith(trimmed, "OR(")) { return parseOrExpression(trimmed.substr(3, trimmed.size() - 4)); } if (startsWith(trimmed, "NOT(")) { return parseNotExpression(trimmed.substr(4, trimmed.size() - 5)); } return parseSingleNode(trimmed); } unique_ptr<ExpressionNode> Parser::parseAndExpression(const string& expr) { cout << "Parsing AND: " << expr << endl; // 调试输出 auto parts = splitComponents(expr); // 输出分割结果 cout << "AND parts (" << parts.size() << "): "; for (const auto& p : parts) cout << "[" << p << "] "; cout << endl; vector<unique_ptr<ExpressionNode>> children; for (const auto& part : parts) { children.push_back(parseLogicalExpression(trim(part))); } return make_unique<AndNode>(move(children)); } unique_ptr<ExpressionNode> Parser::parseOrExpression(const string& expr) { auto parts = splitComponents(expr); vector<unique_ptr<ExpressionNode>> children; for (const auto& part : parts) { children.push_back(parseLogicalExpression(trim(part))); } return make_unique<OrNode>(move(children)); } unique_ptr<ExpressionNode> Parser::parseNotExpression(const string& expr) { auto parts = splitComponents(expr); if (parts.size() != 1) { throw runtime_error("NOT expression requires exactly one argument"); } return make_unique<NotNode>(parseLogicalExpression(trim(parts[0]))); } // 辅助函数 bool Parser::startsWith(const string& str, const string& prefix) { return str.size() >= prefix.size() && str.compare(0, prefix.size(), prefix) == 0; } string Parser::trim(const string& s) { size_t start = s.find_first_not_of(" \t\n\r"); size_t end = s.find_last_not_of(" \t\n\r"); return (start == string::npos) ? "" : s.substr(start, end - start + 1); } #include "Context.h" #include "component.hpp" #include "HandoverRecordSQlite.h" #include "Registry.h" #include "zbjlComponent.h" #include "zbysComponent.h" #include "zzComponentZBFS.h" #include "zbclComponent.h" #include "zzComponentZBCL.h" #include "zbjlComponentFS.h" #include "zbysComponentFS.h" #include "fsclComponentFS.h" #include "jsjlComponentZKJS.h" #include "jsysComponentZKJS2.h" #include "jsxyComponentZKJS.h" #include "jsysComponentJSZK.h" #include "jsxyclComponentZKJS.h" #include "jsComponentZKJS.h" #include "Parser.h" pugi::xml_document doc; //解析xml配置文件 bool parse_config() { //加载xml文件 if (!doc.load_file("config.xml")) { std::cerr << "Failed to load XML file" << std::endl; return false; } std::cout << "parse_config success" << std::endl; doc.save(std::cout, " ", pugi::format_default); return true; } int main() { try { parse_config(); ComponentRegistry::instance().registerComponent<zbjlComponent>("ZBJLComponent"); ComponentRegistry::instance().registerComponent<zbysComponent>("ZBYSComponent"); ComponentRegistry::instance().registerComponent<zzComponentZBFS>("ZZComponentZBFS"); ComponentRegistry::instance().registerComponent<zbclComponent>("ZBCLComponent"); ComponentRegistry::instance().registerComponent<zzComponentZBCL>("ZZComponentZBCL"); ComponentRegistry::instance().registerComponent<zbjlComponentFS>("ZBJLComponentFS"); ComponentRegistry::instance().registerComponent<zbysComponentFS>("ZBYSComponentFS"); ComponentRegistry::instance().registerComponent<fsclComponentFS>("FSCLComponentFS"); ComponentRegistry::instance().registerComponent<jsjlComponentZKJS>("JSJLComponentZKJS"); ComponentRegistry::instance().registerComponent<jsysComponentZKJS2>("JSYSComponentZKJS2"); ComponentRegistry::instance().registerComponent<jsxyComponentZKJS>("JSXYComponentZKJS"); ComponentRegistry::instance().registerComponent<jsysComponentJSZK>("JSYSComponentJSZK"); ComponentRegistry::instance().registerComponent<jsxyclComponentZKJS>("JSXYCLComponentZKJS"); ComponentRegistry::instance().registerComponent<jsComponentZKJS>("JSComponentZKJS"); std::cout << "component registry success" << std::endl; //std::string xmlEL = R"(<chain name="chain1">(THEN(ZBJLComponent,IF(ZBYSComponent,ZZComponentZBFS,IF(ZBCLComponent,THEN(ZBJLComponentFS,ZBYSComponentFS,IF(FSCLComponentFS,THEN(JSJLComponentZKJS,IF(JSYSComponentZKJS2,JSComponentZKJS,JSXYComponentZKJS)),THEN(JSJLComponentZKJS,JSYSComponentJSZK,JSXYCLComponentZKJS))),ZZComponentZBCL))))</chain>)"; //std::string xmlEL = R"(<chain name="复杂逻辑链">(IF(AND(ZBYSComponent,JSYSComponentJSZK),JSXYComponentZKJS,JSXYComponentZKJS,JSXYComponentZKJS),THEN(ZZComponentZBFS,JSComponentZKJS))</chain>)</chain>)"; std::string xmlEL = R"(<chain name="复杂逻辑链">THEN(IF(AND(ZBYSComponent,JSYSComponentJSZK),JSXYComponentZKJS,JSXYComponentZKJS),THEN(ZZComponentZBFS,JSComponentZKJS))</chain>)"; std::string expr = xmlEL.substr(xmlEL.find(">") + 1, xmlEL.rfind("<") - xmlEL.find(">") -1); Parser parser; auto ast = parser.parse(expr); std::cout << "parse EL success" << std::endl; Context ctx; doc.save(std::cout, " ", pugi::format_default); ast->execute(ctx); } catch (const std::exception& e) { std::cerr << "ERROR : " << e.what() << std::endl; return 1; } return 0; } #include "IfNode.h" IfNode::IfNode(std::unique_ptr<ExpressionNode> condition,std::unique_ptr<ExpressionNode> thenBranch, std::unique_ptr<ExpressionNode> elseBranch) :condition_(std::move(condition)), thenBranch(std::move(thenBranch)), elseBranch(std::move(elseBranch)) { } void IfNode::execute(Context& ctx) { // 执行条件表达式节点 condition_->execute(ctx); // 获取条件结果(约定输出存储在"output"中) bool result = (ctx.get("output") == "true"); if (result) { if (thenBranch) thenBranch->execute(ctx); } else { if (elseBranch) elseBranch->execute(ctx); } } 程序只执行ZBYSComponent怎么改
时间: 2025-07-24 21:30:55 浏览: 2
<think>我们面对的问题:修改C++程序以确保执行流程仅作用于ZBYSComponent,跳过其他组件。
根据引用[1]中提到的组件化思想,我们可以通过设计来隔离不同组件的执行。具体思路如下:
1. 在程序执行流程中,识别当前正在处理的组件类型。
2. 如果当前组件是ZBYSComponent,则执行相应的逻辑;否则,跳过执行。
实现方式可能有两种:
a) 在调用组件的通用接口处进行条件判断。
b) 修改组件调度逻辑,只将ZBYSComponent加入执行队列。
假设我们有一个组件基类,所有组件都继承自该基类,并且有一个虚函数`Execute`用于执行组件逻辑。我们可以这样修改:
方案一:在组件的执行函数中加入条件判断
```cpp
class BaseComponent {
public:
virtual void Execute() = 0;
virtual std::string GetComponentName() const = 0;
// ... 其他成员函数
};
class ZBYSComponent : public BaseComponent {
public:
void Execute() override {
// ZBYSComponent的执行逻辑
}
std::string GetComponentName() const override {
return "ZBYSComponent";
}
};
class OtherComponent : public BaseComponent {
public:
void Execute() override {
// 其他组件的执行逻辑
}
std::string GetComponentName() const override {
return "OtherComponent";
}
};
// 在调度执行的地方,我们可以这样写:
void ExecuteComponent(BaseComponent* component) {
// 只执行名为ZBYSComponent的组件
if (component->GetComponentName() == "ZBYSComponent") {
component->Execute();
}
}
```
方案二:在调度层只收集需要执行的组件(推荐)
如果我们在程序中有个组件列表,我们可以只将ZBYSComponent加入执行列表:
```cpp
std::vector<BaseComponent*> allComponents; // 所有组件
std::vector<BaseComponent*> componentsToExecute;
for (auto* comp : allComponents) {
if (comp->GetComponentName() == "ZBYSComponent") {
componentsToExecute.push_back(comp);
}
}
// 然后只执行componentsToExecute中的组件
for (auto* comp : componentsToExecute) {
comp->Execute();
}
```
但是,如果程序结构不是这样,而是有一个固定的执行流程,其中会调用所有组件的执行函数,那么我们可以修改这个流程,只执行特定的组件。
另外,引用[4]中提到的finally机制可以用于确保在离开作用域时执行某些清理工作,但这里可能不直接相关。
根据引用[2]中关于异常排查的经验,我们修改代码后要确保不会引入新的问题,比如其他组件被跳过是否会影响程序整体逻辑?需要根据实际需求来决定。
因此,具体修改取决于程序的结构。如果程序已经按照组件化设计,那么方案二更清晰,因为它直接过滤了要执行的组件。如果无法控制组件的收集过程,则方案一更直接。
请根据实际代码结构选择合适的方式。
注意:如果组件名称的字符串比较觉得效率低或者容易出错(比如名称写错),我们可以考虑使用枚举或者类型信息(typeid)来识别组件类型。
使用typeid的示例:
```cpp
#include <typeinfo>
void ExecuteComponent(BaseComponent* component) {
if (typeid(*component) == typeid(ZBYSComponent)) {
component->Execute();
}
}
```
或者使用枚举标识:
```cpp
enum ComponentType {
CT_Unknown,
CT_ZBYS,
CT_Other
};
class BaseComponent {
public:
virtual ComponentType GetType() const { return CT_Unknown; }
// ...
};
class ZBYSComponent : public BaseComponent {
public:
ComponentType GetType() const override { return CT_ZBYS; }
// ...
};
// 然后判断
if (component->GetType() == CT_ZBYS) {
component->Execute();
}
```
使用枚举或类型信息可以避免字符串比较的开销和错误。
总结:根据你的程序架构,选择在调度处过滤组件,或者在执行函数中判断组件类型,只执行目标组件。
请结合你的代码实际情况进行修改。</think>要确保C++程序仅执行特定组件ZBYSComponent并跳过其他组件,可以结合组件化设计和执行流程控制来实现。以下是具体实现方案:
### 解决方案
1. **组件识别机制**
```cpp
// 组件基类添加标识接口
class BaseComponent {
public:
virtual std::string GetName() const = 0;
virtual void Execute() = 0;
};
// 特定组件实现
class ZBYSComponent : public BaseComponent {
public:
std::string GetName() const override {
return "ZBYSComponent";
}
void Execute() override {
// ZBYS组件的执行逻辑
}
};
```
2. **组件执行调度器**
```cpp
class ComponentScheduler {
public:
void AddComponent(std::unique_ptr<BaseComponent> comp) {
components_.push_back(std::move(comp));
}
void ExecuteTargetComponent(const std::string& targetName) {
for (auto& comp : components_) {
if (comp->GetName() == targetName) {
comp->Execute();
return; // 找到目标组件后立即返回
}
}
throw std::runtime_error("Target component not found");
}
private:
std::vector<std::unique_ptr<BaseComponent>> components_;
};
```
3. **使用示例**
```cpp
int main() {
ComponentScheduler scheduler;
// 注册各种组件
scheduler.AddComponent(std::make_unique<ZBYSComponent>());
scheduler.AddComponent(std::make_unique<OtherComponent>());
scheduler.AddComponent(std::make_unique<AnotherComponent>());
// 仅执行ZBYSComponent
try {
scheduler.ExecuteTargetComponent("ZBYSComponent");
} catch (const std::exception& e) {
std::cerr << "执行错误: " << e.what() << std::endl;
}
return 0;
}
```
### 关键设计要点
1. **组件隔离**
- 每个组件实现独立类,继承自公共接口
- 通过`GetName()`方法提供唯一标识符
- 符合组件化设计原则[^1]
2. **执行控制**
- 调度器遍历组件列表时使用短路返回
- 找到目标组件后立即执行并终止搜索
- 未找到时抛出明确异常
3. **资源管理**
- 使用`std::unique_ptr`自动管理组件生命周期
- 避免内存泄漏风险
4. **错误处理**
- 异常捕获机制确保程序健壮性
- 符合C++异常处理最佳实践[^2]
### 扩展优化
1. **使用工厂模式创建组件**
```cpp
class ComponentFactory {
public:
static std::unique_ptr<BaseComponent> Create(const std::string& name) {
if (name == "ZBYSComponent")
return std::make_unique<ZBYSComponent>();
// 其他组件创建逻辑...
}
};
```
2. **添加执行日志**
```cpp
void ExecuteTargetComponent(const std::string& targetName) {
std::cout << "搜索组件: " << targetName << std::endl; // 日志输出
for (auto& comp : components_) {
if (comp->GetName() == targetName) {
std::cout << "执行组件: " << targetName << std::endl;
comp->Execute();
return;
}
}
// ...
}
```
3. **性能优化**
- 使用`std::unordered_map`存储组件
- $O(1)$时间复杂度查找:
```cpp
std::unordered_map<std::string, std::unique_ptr<BaseComponent>> components_;
void AddComponent(std::unique_ptr<BaseComponent> comp) {
components_[comp->GetName()] = std::move(comp);
}
```
此方案确保程序只执行指定的ZBYSComponent,同时保持代码的可扩展性和可维护性,符合现代C++组件化设计理念[^1]。
阅读全文
相关推荐



















