You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将C++类成员方法排队运行至资源上限?求优化方案

面向对象场景下的成员函数优先级队列分批执行方案优化

问题描述

我有多个继承自父类A的子类对象,每个对象包含多个不同名称的成员函数。受资源限制无法一次性运行所有函数,希望把这些函数按优先级加入队列,分批执行。

尝试的错误实现

第一种代码因成员函数指针声明错误,触发C++编译报错:C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function,代码如下:

class A;
class Token;

list<Token> tokenList;

class Token{
public:
    A* a; // 可以是A或A的子类对象
    int* function;
};

class A {
public:
    A() {
        Token token = Token();
        token.a = this;
        token.function = &A::hello;
        tokenList.push_back(token);
    }
    int hello(){
            cout << "hello" << endl;
            return 0;
    }
    
};

虚函数实现的局限

第二种通过虚函数实现的代码可运行,但不够优雅,且无法支持子类向队列传入多个不同函数,代码如下:

class A;
list<A*> aList;

class A {
public:
    virtual int funct();
};
class B : public A{
public:
    virtual int funct(){
        hello();
        return 0;
    }
    int hello(){
        cout << "hello" << endl;
        return 0;
    }
};
int main(){
// 循环从列表中取出对象并运行函数,直到列表为空或达到最大运行函数数量
}

自行修正的方案

我自行修正的方案为:将Token类中的int* function;改为int (A::*function)();,并通过以下代码调用成员函数:

A tmp = A();

Token token = *tokenList.begin();
A *a = token.a;
(a->*token.function)();
}

更优实现方式

方案1:使用std::function+std::bind封装任务

利用std::function包装任意可调用对象的特性,结合std::bind绑定成员函数和对象实例,再用std::priority_queue实现按优先级排队,是C++11后推荐的灵活方案。

#include <iostream>
#include <queue>
#include <functional>

// 定义带优先级的任务结构体
struct Task {
    int priority; // 数字越大优先级越高
    std::function<int()> func;

    // 重载比较运算符,让队列按优先级降序排列
    bool operator<(const Task& other) const {
        return priority < other.priority;
    }
};

std::priority_queue<Task> taskQueue;

class A {
public:
    void addTasks() {
        // 绑定当前对象的成员函数,按优先级加入队列
        taskQueue.push({2, std::bind(&A::hello, this)});
        taskQueue.push({1, std::bind(&A::world, this)});
    }

    int hello() {
        std::cout << "A::hello" << std::endl;
        return 0;
    }

    int world() {
        std::cout << "A::world" << std::endl;
        return 0;
    }
};

class B : public A {
public:
    void addSubTasks() {
        // 子类自定义函数也可按优先级加入队列
        taskQueue.push({3, std::bind(&B::foo, this)});
        taskQueue.push({2, std::bind(&B::bar, this)});
    }

    int foo() {
        std::cout << "B::foo" << std::endl;
        return 0;
    }

    int bar() {
        std::cout << "B::bar" << std::endl;
        return 0;
    }
};

int main() {
    A aObj;
    B bObj;

    aObj.addTasks();
    bObj.addSubTasks();

    // 分批执行任务,示例每次执行2个
    const int batchSize = 2;
    int count = 0;
    while (!taskQueue.empty() && count < batchSize) {
        Task currTask = taskQueue.top();
        taskQueue.pop();
        currTask.func();
        count++;
    }

    // 剩余任务可在后续批次执行
    return 0;
}

方案2:用Lambda表达式简化绑定

如果觉得std::bind不够简洁,可直接用Lambda捕获对象指针,写法更灵活:

// A类addTasks中替换为:
taskQueue.push({2, [this]() { return this->hello(); }});
taskQueue.push({1, [this]() { return this->world(); }});

// B类addSubTasks中替换为:
taskQueue.push({3, [this]() { return this->foo(); }});
taskQueue.push({2, [this]() { return this->bar(); }});

方案对比

  • 成员函数指针方案:语法繁琐,仅支持父类声明的成员函数,子类新增函数需类型转换,易出错
  • 虚函数方案:仅能绑定固定的单个虚函数,无法支持多函数入队,扩展性差
  • std::function方案:灵活度高,支持任意可调用对象,代码可读性强,适配所有成员函数(父类、子类均可),还能轻松扩展任务属性

内容的提问来源于stack exchange,提问作者BankruptGreek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 00:31:02