LINUX.ORG.RU

Не получается создать свой QTimer c шахматами и поэтессами

 


0

1

Как выглядит:

class TimerImproved : public QTimer
{
    Q_OBJECT

    TimerImproved(QObject* parent) : QTimer(parent)
    {
      connect(this, SIGNAL(QTimer::timeout()), this, SLOT(resettime()));
    }

    int start()
    {
      m_time.start();
      return QTimer::start(); //ошибка: использование пустого (void) значения
    }

    int start(int msec)
    {
      m_time.start();
      return QTimer::start(msec); //ошибка: использование пустого (void) значения
    }

    int timeLeft()
    {
      return QTimer::interval()-m_time.elapsed();
    }

  private slots:

    void resettime()
    {
      m_time.restart();
    }

  private:
    QTime m_time;
};
Не могу понять, что я делаю не так?

★★

А как оно, собственно, должно работать?

Зачем используется QTime?

Y ★★ ()
Ответ на: комментарий от Y

Весь замес в добавлении timeLeft() - в оригинальном QTimer такой фичи нет. А QTime удачно подходит для ее реализации - со стартом таймера m_time принимает значение текущего времени и начинает отсчет от него. Когда нужно узнать, сколько еще будет работать таймер - из времени, в течение которого он должен работать, вычитается время, прошедшее с начала его работы.

netcat ★★ ()
Ответ на: комментарий от Y

в коде в комментариях указаны конкретные ошибки компиляции

netcat ★★ ()
Ответ на: комментарий от netcat

QTimer::start возвращает void, а функция start возвращает int.

Чтобы переопределить функцию start нужно написать void start([int]) и делать this->start() без return.

Получится как-то так:

    void start()
    {
      m_time.start();
      this->start(); //ошибка: использование пустого (void) значения
    }

    void start(int msec)
    {
      m_time.start();
      this->start(msec); //ошибка: использование пустого (void) значения
    }
Y ★★ ()
class TimerImproved : public QTimer
{
    Q_OBJECT
// <---------------
    TimerImproved(QObject* parent) : QTimer(parent)

Там public: не пропущен?

schizoid ★★★ ()

А ещё

Где виртуальный деструктор, где переопределённый stop(), почему resettime перезапускает, а не останавливает время и в timeLeft у тебя при времени, большем, чем интервал, будут отрицательные значения.

schizoid ★★★ ()
Ответ на: А ещё от schizoid

Разгадка одна - я нуб в C++ и Qt.

netcat ★★ ()

Ты делаешь очень плохие вещи: не определяешь виртуальный деструктор, кастишь void к int'у (на что у тебя собственно и жалуется компилятор), переопределяешь не виртуальные функции, используешь наследование вместо агрегации… Вопрос закрытости конструктора оставим на твоей совести. Но вообще этот код оторвёт тебе обе ноги при первом удобном случае.

KblCb ★★★★★ ()
Ответ на: А ещё от schizoid

а зачем виртуальный деструктор?

nanoolinux ★★★★ ()
Ответ на: комментарий от KblCb

И что плохого в переопределении не виртуальных функций и использовании наследования?

netcat ★★ ()
Ответ на: комментарий от nanoolinux

Невиртуальный деструктор не вызовет деструкторы родительских классов. Утечка памяти и всё такое. В гугле сотни информации на эту тему.

schizoid ★★★ ()
Ответ на: комментарий от netcat

что плохого в переопределении не виртуальных функций

Для понимания ответа на этот вопрос тебе придётся выучить, что такое полиморфизм.

что плохого в использовании наследования

А для этого - объектно-ориентированный дизайн.

schizoid ★★★ ()
Ответ на: комментарий от netcat

Такое переопределение никак не учавствует в динамическом связывание, то есть как минимум делает код труднее для чтения и как максимум приведёт к досадной ошибке примерно в таком коде:

#include <iostream>

class A
{
public:
    A() = default;
    virtual ~A(){};

    void f(){ std::cout << "A::f()" << std::endl; }
};

class B : public A
{
public:
    B() = default;
    virtual ~B(){};

    void f(){ std::cout << "B::f()" << std::endl; }
};                                                                   

int main( void )
{             
    A* ptr = new B;
    ptr->f();
}

Поведение этого кода протеворечит логике наследования как «есть разновидность» что в высшей мере неожиданно. То есть по сути класс топикстартера не является разновидностью QTimer'а. Так что ему следовало вложить QTimer в свой класс, изобразить тот интерфейс который будет дёргать QTimer.

KblCb ★★★★★ ()
Ответ на: комментарий от schizoid

ты уверен, что витруальный деструктор дочернего класса вызовет невиртуальный деструктор родительского?

nanoolinux ★★★★ ()
Ответ на: комментарий от netcat

ты породил какой-то класс-монстр, будто первые 5 минут за компьютером сидишь :)

I-Love-Microsoft ★★★★★ ()

QTimer и так примитивен до жути (startTimer() - выброс сигнала из timerEvent - killTimer()), так что наследоваться от него незачем, лучше свой с нуля писать

annulen ★★★★★ ()
Ответ на: комментарий от schizoid

QTimer наследник QObject, у которого деструктор объявлен виртуальным. А если в базовом класса он объявлен виртуальным, то каким он будет во всех классах-наследниках?

anonymous ()
Ответ на: комментарий от schizoid

Если в базовом класе определил виртуальный деструктор, то он для всех потомков останется виртуальным.

Gorthauer ★★★★★ ()
Ответ на: комментарий от Gorthauer

Век живи, век учись

А меня всю жизнь всякие сениоры заставляли явно писать virtual.

// А это ещё и для виртуальных функций работает, обалдеть.

schizoid ★★★ ()

Как выглядит:

Внимание: прочитайте личное обращение Джимми описание разметки LORCODE

anonymous ()
Ответ на: Век живи, век учись от schizoid

А меня всю жизнь всякие сениоры заставляли явно писать virtual.

Это на случай если во время глобальной переделки программы класс со своими наследниками будет оторван от базового класса. Дабы случайно не случился косяк который потом хрен найдешь, перестраховщики короче...

SSZB ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.