Я пытаюсь передать собственный указатель класса (с использованием полиморфизма) другому, используя механизм сигнальных слотов. В основном у меня есть базовый класс и несколько производных классов (они не расширены из QObject), и я пытаюсь передать базовый класс другому потоку, используя механизм сигнальных слотов, как описано в примере ниже. Когда я делаю это, я могу успешно передать указатель базового класса в другой поток, но когда я пытаюсь уменьшить его или вызвать виртуальный метод, я получаю исключение sigsegv. Я перебрал много статей, но не смог найти правильного решения, кто-нибудь сталкивался с такой проблемой раньше?
Это часть, которую я создал рабочие потоки
qRegisterMetaType<SecondMessage>();
for (const auto& receiver : glimpseReceivers) {
QThread *thread = new QThread();
receiver->moveToThread(thread);
QObject::connect(thread, SIGNAL(started()), receiver.get(), SLOT(start()));
QObject::connect(receiver.get(), SIGNAL(finished()), thread, SLOT (quit()));
QObject::connect(receiver.get(), SIGNAL (finished()), receiver.get(), SLOT (deleteLater()));
QObject::connect(thread, SIGNAL(finished()), thread, SLOT (deleteLater()));
QObject::connect(receiver.get(),&MAGlimpseReceiver::sequenceNumberReceived,this,&MAItchManager::sequenceReceived);
QObject::connect(receiver.get(),&MAGlimpseReceiver::glimpseDataSignal,this,&MAItchManager::itchDataReceived);
thread->start();
threadList.push_back(thread);
}
Это сигнал, который вызывается из рабочего потока в основной поток:
void MAGlimpseReceiver::glimpseDataReceived(ITradeMessagePtr tradeMessage) {
if (tradeMessage != nullptr) {
spdlog::debug("Glimpse Data Received For Market:{} Part:{} Type:{}",configuration.marketId,configuration.partId,tradeMessage->getType());
emit glimpseDataSignal(tradeMessage.get(),int(configuration.marketId),configuration.partId);
}
}
Это слот в главном потоке, который получает сигнал и попробуйте использовать виртуальный метод
void MAItchManager::itchDataReceived(ITradeMessage* tradeMessage,int marketId,int partId) {
spdlog::debug("Itch Data Received for Market: {} Part: {} Type:{}",marketId,partId,char(tradeMessage->getType()));
if (tradeMessage->isValidMessage()) {
auto itchPackage = std::make_shared<ItchPackage>();
ItchMessage *itchMessage = tradeMessage->getItchMessage();
itchPackage->market = MarketType (marketId);
itchPackage->part = partId;
itchPackage->itchMessage = itchMessage;
if (callBack != nullptr) {
callBack(itchPackage.get());
}
} else {
spdlog::error("Unknown Trade Message Type:{}",tradeMessage->getType());
}
}
И это один из примеров базовых и производных классов, которые я пытаюсь перенести в основной поток. Базовый класс:
class ITradeMessage {
public:
ITradeMessage() {
}
ITradeMessage(const char* message) {
}
virtual ~ITradeMessage() {
}
ItchMessageType getType() const {
return type;
}
virtual ItchMessage * getItchMessage() = 0;
bool isValidMessage() const {
return validMessage;
}
protected:
ItchMessageType type = ItchMessageType::Msg_None;
bool validMessage = false;
};
using ITradeMessagePtr = std::shared_ptr<ITradeMessage>;
Производный класс:
class SecondMessage: public ITradeMessage {
public:
SecondMessage() = default;
SecondMessage(const char* message);
SecondMessage(const SecondMessage& obj);
~SecondMessage() = default;
friend std::ostream& operator<<(std::ostream&, const SecondMessage&);
ItchMessage *getItchMessage();
};
Q_DECLARE_METATYPE(SecondMessage); //Compiler gives this warning but still compiles: Excess elements in struct initializer
using SecondMessagePtr = std::shared_ptr<SecondMessage>;