Russian Qt Forum
Ноябрь 24, 2024, 01:28 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: [РЕШЕНО] Непонятное поведение виртуальных методов  (Прочитано 2155 раз)
vunder
Гость
« : Октябрь 12, 2010, 08:52 »

Объявил следующий класс:
Код
C++ (Qt)
class UnpProtocol : public QThread
{
Q_OBJECT
 
private slots:
   void onThreadStop();
 
protected:
   bool m_connected;
   virtual void unpDisconnect();
   virtual void unpConnect();
   void run();
 
protected slots:
   virtual void onTcpConnected();
   virtual void onTcpDisconnected();
   virtual void onTcpError(QAbstractSocket::SocketError);
 
public:
   UnpProtocol();
   ~UnpProtocol();
 
signals:
   void needRegistration();
   void registrationResult(bool);
 
};
 
 
UnpProtocol::UnpProtocol() :
       QThread(0)
{
   this->moveToThread(this);
}
 
UnpProtocol::~UnpProtocol()
{
   exit();
   wait();
}
 
void UnpProtocol::run()
{
   connect(fSocket, SIGNAL(connected()),
           this,    SLOT(onTcpConnected()));
   connect(fSocket, SIGNAL(disconnected()),
           this,    SLOT(onTcpDisconnected()));
   connect(fSocket, SIGNAL(readyRead()),
           this,    SLOT(onTcpReadyRead()));
   connect(fSocket, SIGNAL(error(QAbstractSocket::SocketError)),
           this,    SLOT(onTcpError(QAbstractSocket::SocketError)));
   connect(this,    SIGNAL(finished()),
                    SLOT(onThreadStop()));
   unpConnect();
//    unpDisconnect();
   exec();
}
 
void UnpProtocol::unpConnect()
{
   m_connected = false;
}
 
void UnpProtocol::unpDisconnect()
{
   m_connected = false;
}
 
void UnpProtocol::onTcpDisconnected()
{
#ifdef QT_DEBUG
   qDebug() << "Disconnet form address";
#endif
}
 
void UnpProtocol::onTcpConnected()
{
#ifdef QT_DEBUG
   qDebug() << "Connected to address";
#endif
}
 
void UnpProtocol::onTcpError(QAbstractSocket::SocketError err)
{
#ifdef QT_DEBUG
   QString strError =
       "Error: " + (err == QAbstractSocket::HostNotFoundError ?
                    "The host was not found." :
                    err == QAbstractSocket::RemoteHostClosedError ?
                    "The remote host is closed." :
                    err == QAbstractSocket::ConnectionRefusedError ?
                    "The connection was refused." :
                    QString("other error - %1").arg(fSocket->errorString())
                   );
   qDebug() << strError;
#endif
   m_connected = false;
}
 
void UnpProtocol::onThreadStop()
{
   if (m_connected)
       unpDisconnect();
}
 
Объявил потомка
Код
C++ (Qt)
class UnpClientProtocol: public UnpProtocol
{
Q_OBJECT
 
private:
   bool selfDisconnect;
   int timerId;
 
protected:
   void unpConnect();
   void unpDisconnect();
   void run();
   void timerEvent(QTimerEvent* event);
 
protected slots:
   void onTcpConnected();
   void onTcpDisconnected();
   void onTcpError(QAbstractSocket::SocketError);
 
public:
   UnpClientProtocol();
 
};
 
 
UnpClientProtocol::UnpClientProtocol() :
       UnpProtocol(), selfDisconnect(false), timerId(0)
{
 
}
 
void UnpClientProtocol::run()
{
   fSocket = new QTcpSocket(this);
   UnpProtocol::run();
   if (timerId)
       killTimer(timerId);
}
 
void UnpClientProtocol::timerEvent(QTimerEvent *event)
{
   UnpProtocol::timerEvent(event);
   if (event->timerId() == timerId)
   {
#ifdef QT_DEBUG
       qDebug() << "Reconnect timer event! Trying to reconnect...";
#endif
       killTimer(timerId);
       timerId = 0;
       unpConnect();
   }
}
 
void UnpClientProtocol::unpConnect()
{
   selfDisconnect = false;
   UnpProtocol::unpConnect();
   fSocket->connectToHost(hostAddress, portNumber);
}
 
void UnpClientProtocol::unpDisconnect()
{
   UnpProtocol::unpDisconnect();
   selfDisconnect = true;
   fSocket->disconnectFromHost();
   fSocket->waitForDisconnected();
}
 
void UnpClientProtocol::onTcpConnected()
{
   UnpProtocol::onTcpConnected();
   emit needRegistration();
}
 
void UnpClientProtocol::onTcpDisconnected()
{
   UnpProtocol::onTcpDisconnected();
   if (!selfDisconnect)
   {
       m_connected = false;
       emit registrationResult(m_connected);
       if (timerId)
           killTimer(timerId);
#ifdef QT_DEBUG
       qDebug() << "Starting reconnect timer";
#endif
       timerId = startTimer(5000);
   }
}
 
void UnpClientProtocol::onTcpError(QAbstractSocket::SocketError err)
{
   UnpProtocol::onTcpError(err);
   emit registrationResult(m_connected);
   if (timerId)
       killTimer(timerId);
#ifdef QT_DEBUG
   qDebug() << "Starting reconnect timer";
#endif
   timerId = startTimer(5000);
}
 

Проблема в том, что при срабатывании слота UnpProtocol::onThreadStop() и вызове внутри метода unpDisconnect() вызывается метод UnpProtocol::unpDisconnect(), а не UnpClientProtocol::unpDisconnect(). Причем, если вызвать unpDisconnect() из метода UnpProtocol::run() (я закомментировал строку), то нормально срабатывает UnpClientProtocol::unpDisconnect().
Подскажите, где ошибся!!!
« Последнее редактирование: Октябрь 12, 2010, 21:18 от vunder » Записан
SASA
Гость
« Ответ #1 : Октябрь 12, 2010, 14:23 »

Скорее всего UnpProtocol::onThreadStop() отрабатывает из деструктора UnpProtocol().
Записан
vunder
Гость
« Ответ #2 : Октябрь 12, 2010, 21:18 »

Да, так и было. Остановка процесса выполняется в деструкторе UnpProtocol, а завершение работы производилось просто delete unp. Получается, что при выполнении деструктора контекст потомка уже "потерян" или удален. Изменил немного код и перед удаление экземпляра класса вставил unp->quit(); unp->wait(); delete unp; И все заработало как надо
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.103 секунд. Запросов: 20.