线程消息传递或更好:在"大师班"中访问其他班级的成员

Thread messaging or better: Accessing members from other class in "master-class"

本文关键字:访问 成员 其他 大师 消息传递 更好 线程      更新时间:2023-10-16
  • 首先: 很抱歉标题可能不好,文字太多了 - 这是因为我试图尽可能准确地描述我的问题! :)

    • 如果我的原则思想不清楚,请添加评论 - 我会尝试重写问题(因为英语不是我母亲的语言(。

    • 如果有更好的方法,我也很高兴你能和我分享你的想法!

背景

我目前正在C++开发一个消息传递系统,用于线程之间的交互。 主要思想是拥有一个类 - 我们称它们为保存我的消息数据的SharedMessage。分配值后,我想将它们添加到队列中,以便我的线程可以使用存储在这些消息中的信息。

问题是,消息的内容取决于其类型。 例如,有多种"消息类型",但所有这些不同的类型都应保存在同一个队列中(例如messages(。


第一个/最简单的想法

我正在考虑的最简单的方法是将列表args_string_作为成员变量添加到我的SharedMessage类中,并使用getter和setter访问列表的内容。为了区分不同的消息类型,我使用了另一个名为messageType的成员变量。 下面是一个示例:

class SharedMessage{
public: 
void setMessageType(int type)(); // sets the message type
void addArg(std::string arg)(); // add an item to the list
void getArgs(); // Should return the list args_string_
private:
int messageType = 1;
std::vector<string> args_string_;
};

现在我只是填充我的类列表,分配一个messageType,然后将它们添加到我的队列中。我的线程可以访问它们并从我的队列中删除它们(队列messages(。

问题是:这不是一种非常优雅的方式。我总是需要知道我的论点需要以什么顺序处理。


我的假设想法:

由于上述问题,我更多地考虑使用模板或继承之类的东西。我不知道是否有类似的东西——例如,动态继承自其他类。

让我们来看看我在想的想法:

在这种情况下,我再次获得了我的SharedMessage类 - 但现在我没有添加任何成员。这是因为我想稍后在运行时/实例化/编译时定义成员(这甚至可能吗?(——也许与 STL 类这样做的方式相同。

// This should be my "master"-class. The queue should be able to hold elements of this type.
class SharedMessage 
{ }; 

现在我得到了两个"虚拟"命令:Command1Command2

// This is one possible command that can hold a string ("command1")
// They can be accessed by using getters/setters
class Command1{
std::string command1;
void setCommand1(std::string cmd1);
std::string getCommand1();
}
// Second possible command. Note that in this case my command holds an integer ("counter")
class Command2{
double counter;
void setCounter(int cnt);
int getCounter();
}

这些命令具有不同的成员。
这个想法现在使用类似于以下代码的东西。在我的main中,我创建了上述队列messages,它可以容纳SharedMessage类型的实例。 现在这就是它变得有趣的地方。我希望能够做这样的事情。输入一个SharedMessage,但使用从Command1继承的成员(也许类似于SharedMessage<Command1> sharedmessage;? 之后我可以从Command1使用这些成员,除了sharedmessageSharedMessage类型!

(这就是我想访问成员的方式?!例如:

main() {
// This is my queue.
queue <SharedMessage> messages; 
// I want to create a Shared message of type Command1
SharedMessage<Command1> sharedmessage;
// This is the interesting line. Is there a function for this dynamic "member generation". Like inheritance (but in a dynamic way/like templates)?
sharedmessage.setCommand1("My command); // I’m using Command1 member beside “sharedmessage” is of datatype “SharedMessage”
// Add to queue
messages.push(sharedmessage);
// And this should also work :
SharedMessage<Command2> sharedmessage2;
message.setCounter(172);
// Add second message with different content to queue
messages.push(sharedmessage);
}

如果使队列存储指向消息的指针,则可以使用继承。它看起来像这样:

class SharedMessage {...};
class Command1: public SharedMessage {...};
class Command2: public SharedMessage {...};
...
std::queue<SharedMessage *> messages;
Command1 message1;
Command2 message2;
messages.push(&message1);
messages.push(&message2);

缺点是您的队列现在不再存储消息本身,而只是存储指针,因此您需要某种方法来管理它们的生命周期。一种可能性是使用std::queue<std::unique_ptr<SharedMessage>>,并将消息添加到队列中,如下所示:

messages.push(std::make_unique<Command1>());
// or:
auto message2 = std::make_unique<Command2>();
messages.push(std::move(message2));

要从队列中获取消息,请编写如下内容:

std::unique_ptr<SharedMessage> message = std::move(messages.front());
messages.pop();

您不能像上一个示例中那样使用模板,因为如果您有template<typename T> class SharedMessage {...},那么std::queue<SharedMessage>不会编译,因为SharedMessage本身不是真正的类型。你可以制作一个std::queue<SharedMessage<Command1>>,但当然你不能用它来存储SharedMessage<Command2>