线程消息或更好:访问“大师班”中其他班级的成员
Posted
技术标签:
【中文标题】线程消息或更好:访问“大师班”中其他班级的成员【英文标题】:Thread messaging or better: Accessing members from other class in "master-class" 【发布时间】:2020-01-24 22:16:53 【问题描述】:首先:对不起,可能是错误的标题和这么多的文字 - 这是因为我试图尽可能准确地描述我的问题! :)
如果我的主要想法不清楚,请添加评论 - 我会尝试重写问题(因为英语不是我的母语)。
如果有更好的方法可以做到这一点,我也很高兴您能与我分享您的想法!
背景
我目前正在使用 C++ 开发一个消息传递系统,用于线程之间的交互。
主要思想是创建一个类——我们称它们为SharedMessage
,它保存着我的消息数据。分配值后,我想将它们添加到队列中,以便我的线程可以处理存储在这些消息中的信息。
问题在于,消息的内容取决于其类型。例如。有多种“消息类型”,但所有这些不同的类型都应保存在同一个队列中(例如messages
)。
第一个/最简单的想法
我想到的最简单的方法就是将一个列表 args_string_
作为成员变量添加到我的 SharedMessage
-class 并使用 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
)中访问和删除它们。
问题:这不是一个非常优雅的方式。我总是需要知道我的论点需要按什么顺序处理。
我的假设:
由于上述问题,我更多地考虑使用模板或继承之类的东西。我不知道是否有类似的东西 - e。 G。从其他类动态继承。
让我们看看我的想法:
在这种情况下,我再次获得了SharedMessage
-class——但现在我没有添加任何成员。这是因为我想稍后在运行时/实例化/编译时定义成员(这甚至可能吗?)——可能与 STL-Class 执行此操作的方式相同。
// This should be my "master"-class. The queue should be able to hold elements of this type.
class SharedMessage
;
现在我得到了两个“虚拟”命令:Command1
、Command2
// 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
的这些成员,除了sharedmessage
的类型是SharedMessage
!
(这就是我想要访问成员的方式?!) 例如:
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);
【问题讨论】:
【参考方案1】:如果您使队列存储指向消息的指针,则可以使用继承。它看起来像这样:
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>
。
【讨论】:
我也想过你指出的想法(我之前什至实现过)但我没有使用unique_ptr
。由于没有其他选择,我会尝试实现使用unique_ptr
的想法。以上是关于线程消息或更好:访问“大师班”中其他班级的成员的主要内容,如果未能解决你的问题,请参考以下文章