LINUX.ORG.RU

Объясните поведение Qt

 ,


0

2
class TimePoint{
public:
    QPoint p;
    qint64 t;
    TimePoint(){}
    TimePoint(QPoint _p , int _t){
        p = _p;
        t = _t;
    }
};

//....

QVector <TimePoint> mousePoint;

QVector требует наличие конструктора без параметров, я его сделал пустым. Но при добавлении в вектор элемента происходит что-то странное, как будто-бы правильный конструктор(с моими параметрами) и не был вызван.

TimePoint tmp(QPoint(mouseX , mouseY) ,  QDateTime::currentMSecsSinceEpoch());
//tmp.p = QPoint(mouseX , mouseY);
//tmp.t = QDateTime::currentMSecsSinceEpoch();
//если эти две строчки выше закоментированны то код не работает как надо
mousePoint.push_back(tmp);
★★★

mousePoint.push_back(tmp);

Так у тебя элемент уже есть, тут будет вызван не твой конструктор, а copy ctor.

UVV ★★★★★
()

Все работает, видимо проблема в другом.

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

Зависит от того, что он будет с ним делать внутри.

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

И да, исправил

Просто офигенное исправление которое только ухудшает читаемость и ни на байт не меняет формируемого кода

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

еще как меняет

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

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

которое только ухудшает читаемость

На вкус и цвет... Для кого-то это будет более чем читабельно, сразу видно, что в конструкторе нифига дурного не делается.

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

может быть, но как правильно заметил grondek, все сильно зависит от реализации компилятора

EugeneBas ★★
()

QVector требует наличие конструктора без параметров, я его сделал пустым

И всё ради чего? Ради того, чтобы использовать кривые поделки из Qt, вместо стандартного вектора.

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

Стандартный вектор тоже не может быть полноценно использован с типом без конструктора по умолчанию.

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

И всё ради чего? Ради того, чтобы использовать кривые поделки из Qt, вместо стандартного вектора.

С каких пор стандартные поделки стали лучше Qt'шной реализации?

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

Стандартные вектора неудобно использовать внутри Qt приложения - придется постоянно туда-сюда конвертировать, чтобы полноценно использовать.

И чем конкретно поделки Qt такие кривые?

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

И чем конкретно поделки Qt такие кривые?

Чаще всего проблема в вероисповедании.

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

И чем конкретно поделки Qt такие кривые?

Часто требует конструктор по-умолчанию. Тот-же push_back может (и должен) обходиться без него.

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

полноценно

если под этим подразумевать resize и конструктор explicit vector(size_type count);

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

Часто требует конструктор по-умолчанию. Тот-же push_back может (и должен) обходиться без него.

Я раньше не замечал, а с С++11 стало неприятно пользоваться QMap: его итератор ссылается не на пару ключ-значение, а только на значение, т.о. нормально пробегать по всей коллекции няшным for(v:map) невозможно. Сделано это было вероятно для всяких qdeleteall, которые с новыми плюсами как раз таки уже и не нужны.

Но ни твоего конструктора, ни моих итераторов недостаточно для называния куконтейнеров кривыми :)

staseg ★★★★★
()
Последнее исправление: staseg (всего исправлений: 1)

Как уже сказали, push_back складывает в вектор копии tmp. Определи конструктор копирования. И ещё 5 копеек: обычно как аналог std::vector используют QList.

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

тут будет вызван не твой конструктор, а copy ctor.

Но что это объясняет?

Конструктор C++ при копировании одного объекта в другой работает поэлементно. То есть в переменные экземпляра класса, в который производится копирование, копируются значения из соответствующих переменных экземпляра класса, который копируется

abs ★★★
() автор топика
Ответ на: комментарий от fluorite
#include <QCoreApplication>
#include <QDebug>
#include <QPoint>
#include <QVector>
#include <QDateTime>

class TimePoint{
public:
    QPoint p;
    qint64 t;
    TimePoint() {
        qDebug() << "Default c-tor";
    }
    TimePoint(QPoint _p , int _t) {
        p = _p;
        t = _t;
        qDebug() << "Your c-tor";
    }
    TimePoint(const TimePoint& _point) {
        this->p = _point.p;
        this->t = _point.t;
        qDebug() << "Copy c-tor";
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QVector <TimePoint> mousePoint;

    int mouseX, mouseY;
    mouseX = 42;
    mouseY = 100500;

    TimePoint tmp(QPoint(mouseX , mouseY) ,  QDateTime::currentMSecsSinceEpoch());
    mousePoint.push_back(tmp);

    const TimePoint &tp = mousePoint.at(0);
    qDebug() << "as expected" << tp.p << tp.t;

    return a.exec();
}
Your c-tor 
Copy c-tor 
Copy c-tor 
as expected QPoint(42,100500) 1711915962 
fluorite ★★★★★
()
Ответ на: комментарий от fluorite

ТС, вообще-то, справедливо заметил, что конструктор копирования, формируемый компилятором, в данном случае является корректным. Так что ждём минимальный пример от ТС с указанием того что он ожидал получить и что он получил (если ТС ещё сам не нашёл ошибку в другом месте своего кода).

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

Так что ждём минимальный пример от ТС с указанием того что он ожидал получить и что он получил

Я пытаюсь сделать эффект просто карандаша, для этого рисую много линий в предыдущие координаты мышки, но при этом проверяю время когда эти координаты были получены

for(int i = mousePoint.size()-1 , j = 8; i > 0 && j > 0; i--,j--){
        qDebug() << QDateTime::currentMSecsSinceEpoch() - mousePoint[i].t ;
        if(QDateTime::currentMSecsSinceEpoch() - mousePoint[i].t < 100)
        pi.drawLine(QPoint(mouseX , mouseY) , mousePoint[i].p);
    }

И вот вывод который я получаю - это полное число секунд с юникс эпохи - а это значит что в mousePoint.t = 0;

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

Дык конструктор принимает int, а не quint64 вот и получаешь в 2 раза меньше байт.

Спасибо, точно! А почему int 32 ? операционная система - 64 битная...

abs ★★★
() автор топика

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

Единственное, что тебе надо сделать, это инициализировать quint64 t в конструкторе:

TimePoint() : 
    t( 0 )
{
}

А то там будет лежать по-умолчанию всякая фигня.

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