我是 C++ 的新手,我遇到了一个问题,即我会在类中产生开销。我有一个 QTcpSocket 并从中读取消息并创建对象,例如 MessageJoin、MessagePart、MessageUserData 等。我将这些对象发送到我的客户端并显示它们(+ 进行一些 UI 更新)。
现在我的问题来了。我测试了一些设计技术,但都不是很好:
- 将信号/槽连接中的消息对象的每个参数传递给客户端 - 开销很小但不是那么好看
- 为每个 Message-Type(messageJoinReceived、messageNoticeReceived 等)创建一个方法
- 创建一个方法并使用 dynamic_cast 强制转换每个类并对其进行测试
为了更好地理解,我添加了我的 dynamic_cast 版本。如前所述,代码看起来丑陋且无法使用。我的问题是:
- 有没有更好的方法来做(a)dynamic_cast
- 是否有另一种方法(例如设计模式)来解决这样的问题?也许在类中添加一个方法并返回类型或类似的东西
- 我读到了访问者模式。此模式仅适用于 Getter/Setter 方法中的动态对象类型?
一些旁注
- 我可以使用 RTTI
- 速度不是什么大问题。干净易懂的代码更重要
- 我使用 Qt 并且有可能使用 qobject_cast 和信号/插槽
这是我的代码(Pastebin-Link):
// Default class - contains the complete message (untouched)
class Message
{
public:
QString virtual getRawMessage() { return dataRawMessage; }
protected:
QString dataRawMessage;
};
// Join class - cointains the name of the joined user and the channel
class MessageJoin : public Message
{
public:
MessageJoin(const QString &rawmessage, const QString &channel, const QString &user)
{
dataRawMessage = rawmessage;
dataChannel = channel;
dataUser = user;
}
QString getChannel() { return dataChannel; }
QString getUser(){ return dataUser; }
private:
QString dataChannel;
QString dataUser;
};
// Notice class - contains a notification message
class MessageNotice : public Message
{
public:
MessageNotice(const QString &rawmessage, const QString &text)
{
dataRawMessage = rawmessage;
dataText = text;
}
QString getText() { return dataText;}
private:
QString dataText;
};
// Client code - print message and update UI
void Client::messageReceived(Message *message)
{
if(message)
{
MessageJoin *messagejoin;
MessagePart *messagepart;
MessageNotice *messagenotice;
if((messagejoin = dynamic_cast<MessageJoin *>(message)) != 0)
{
qDebug() << messagejoin->getUser() << " joined " << messagejoin->getChannel();
// Update UI: Add user
}
else if((messagenotice = dynamic_cast<MessageNotice *>(message)) != 0)
{
qDebug() << messagenotice->getText();
// Update UI: Display message
}
else
{
qDebug() << "Cannot cast message object";
}
delete message; // Message was allocated in the library and is not used anymore
}
}