如何获取 class 的所有子对象

How to get all child objects of a class

是否可以检索对象的子对象列表(特定类型)?

例如,在这段代码中,我有一个包含多个可用命令的应用程序。一个函数以这种方式打印所有可用命令,用户知道他可以做什么。
我想遍历 App 中找到的每个 Command 类型的对象来打印他的文档,这样每次在 App 中添加 Command 时文档都会自动更新。

class Command {
public:
    std::string Name;
    std::string Description;
    virtual void Compute() = 0;
};

class StartCommand : public Command {
    std::string Name = "start";
    std::string Description = "Start the process";
    virtual void Compute() {
        // Code to start the process
    }
};

class StopCommand : public Command {
    std::string Name = "stop";
    std::string Description = "Stop the process";
    virtual void Compute() {
        // Code to stop the process
    }
};

class App {
public:
    StartCommand StartCommand;
    StopCommand StopCommand;

    void PrintAvailibleCommands() {
        std::cout << "All availible commands are: " << std::endl;
        for (Command command : this.GetObjects<Command>()) {
            std::cout << command.Name << ": " << command.Description << std::endl;
        }
    }
};

this.GetObjects<Command>() 函数不存在,我想实现。

你有什么想法吗?

这可能会解决您的问题。

#include <cassert>
#include <cstring>
#include <iostream>
#include <vector>

using namespace std;

class Command {
  public:
    std::string Name;
    std::string Description;
    Command(std::string Name, std::string Description)
        : Name(Name), Description(Description) {}
    virtual void Compute() = 0;
};

class StartCommand : public Command {
  public:
    StartCommand() : Command("start", "Start the process") {}
    virtual void Compute() {
        // Code to start the process
        cout << "startcmd compute" << endl;
    }
};

class StopCommand : public Command {
  public:
    StopCommand() : Command("stop", "Stop the process") {}
    virtual void Compute() {
        // Code to stop the process
        cout << "stopcmd compute" << endl;
    }
};

class App {
  public:
    App() {
        commands.push_back(&startCommand);
        commands.push_back(&stopCommand);
    }

    StartCommand startCommand;
    StopCommand stopCommand;

    vector<Command *> commands;

    void PrintAvailableCommands() {
        std::cout << "All available commands are: " << std::endl;
        for (Command *command : commands) {
            std::cout << command->Name << ": " << command->Description
                      << std::endl;
        }
    }
};

int main() {
    App app;

    app.PrintAvailableCommands();
    app.startCommand.Compute();
    app.stopCommand.Compute();

    return 0;
}

通常,我发现当我希望某些东西在某个时候存在时,直接将其放入集合中会更容易。

#include <iostream>
#include <tuple>
#include <string>

struct Command {
    std::string Name;
    std::string Description;
    virtual void Compute() = 0;
};

struct StartCommand : Command {
    std::string Name = "start";
    std::string Description = "Start the process";
    virtual void Compute() {
        // Code to start the process
    }
};

struct StopCommand : Command {
    std::string Name = "stop";
    std::string Description = "Stop the process";
    virtual void Compute() {
        // Code to stop the process
    }
};

struct App {
    std::tuple<StartCommand, StopCommand> commands{};

    template<class Cmd>
    static void PrintCommand(const Cmd &cmd) {
        std::cout << cmd.Name << ": " << cmd.Description << std::endl;
    }

    void PrintAvailibleCommands() {
        std::cout << "All available commands are: " << std::endl;
        std::apply([](const auto &...cmds) { (PrintCommand(cmds), ...); }, commands);
    }
};