2012-04-21 4 views
2

На этой странице:Что явно разделяет значение?

http://qwt.sourceforge.net/class_qwt_plot_curve.html#afd13c94e23520dacbc37b4d0fd036a8b

Метод

void QwtPlotCurve::setRawSamples() 

только сохраняет адреса данных в QwtPlotCurve, что именно то, что я хочу для повышения эффективности.

В то время как:

void QwtPlotCurve::setSamples() 

использует QVector, что более удобно. Но это только «явно разделяемое». Что это значит? сохраняет указатель точно так же, как первый?

Мне нужно добавить точку на график каждые 50 мс. Глубокое копирование данных - не лучшее решение !!! совет?

+0

50 мс обычно достаточно долго, чтобы делать много вещей. –

ответ

7

Это сочетается с концепцией Qt о «неявное совместное использование»:

http://doc.qt.io/archives/qt-4.7/implicit-sharing.html

Даже если вы передаете QVector данных по значению, как параметр в Qt, он не будет копировать память сразу. Он будет делать только копию, если один из векторов изменен.

Я бы подумал, что документация, говоря «явное разделение» в случае setSamples просто обратить внимание на тот факт, что вы передаете в QVectors по ссылке, а не по значению:

void QwtPlotCurve::setSamples(
    const QVector<double> &xData, 
    const QVector<double> &yData 
) 

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

HOWEVER глядя на исходный код, кажется, что под капотом он просто делает неявно разделяемую копию в любом случае. В qwt_plot_curve.cpp мы имеем:

/*! 
    \brief Initialize data with x- and y-arrays (explicitly shared) 

    \param xData x data 
    \param yData y data 
    \sa QwtPointArrayData 
*/ 
void QwtPlotCurve::setSamples(const QVector<double> &xData, 
    const QVector<double> &yData) 
{ 
    setData(new QwtPointArrayData(xData, yData)); 
} 

Мы можем видеть, что QwtPointArrayData объявлен в qwt_point_data.h, как это:

class QWT_EXPORT QwtPointArrayData: public QwtSeriesData<QPointF> 
{ 
public: 
    QwtPointArrayData(const QVector<double> &x, const QVector<double> &y); 
    QwtPointArrayData(const double *x, const double *y, size_t size); 

    virtual QRectF boundingRect() const; 

    virtual size_t size() const; 
    virtual QPointF sample(size_t i) const; 
    const QVector<double> &xData() const; 
    const QVector<double> &yData() const; 

private: 
    QVector<double> d_x; 
    QVector<double> d_y; 
}; 

Код для конструктора в qwt_point_data.cpp только простое присваивание d_x и d_y. Которая возвращается к простому совместному использованию. Таким образом, изменения, внесенные вами в данные, которые вы передали, будут не видны по сюжету; вы будете платить за копию, сделанную в момент такой модификации.

Если бы они просто собирались это сделать, то почему они беспокоились о том, чтобы передавать в const-ссылке (а не только по значению), является для меня загадкой. Единственное «совместное использование», которое происходит здесь, кажется неявным, поэтому я не знаю, что означает «явно разделяемый» комментарий.

+0

Значит ли это, если я добавлю точку в массивы xData, yData, я сразу увижу ее влияние на график? это именно то, что я хочу !!!!!!!!! Я планирую использовать что-то вроде FIFO для построения точек, которые я добавляю к этим массивам. Это то, что я ищу? –

+0

Я заглянул в код и ... ответ - нет. См. Обновление. – HostileFork

+0

Если вы делаете небольшие изменения в векторах и хотите избежать копирования, вы можете попробовать что-то вроде 'myPlot-> setSamples (QVector (), QVector ());' * before * вы вносите какие-либо изменения в векторы, в которые вы проходили. Это даст сюжет для публикации неявно разделяемой ссылки, которую он держит, поэтому вам не придется платить за копию, которая произошла при модификации. Может помочь ... [shrug] – HostileFork

2

Взятое прямо из http://doc.qt.io/archives/qq/qq02-data-sharing-with-class.html

С явным разделением, это ответственность пользователя, а не класс, вызвать отсоединение() перед изменением объекта. Если пользователь забывает называть detach(), все объекты, имеющие одни и те же данные, имеют свое состояние, очень опасный побочный эффект.

Явные общие классы семантически похожи на указатели. Сравните код слева, в котором используется INT *, с что справа, в котором используется фиктивный явно общий Int класс:

int *a = new int(111); Int a(111); 
int *b = a;     Int b = a; 
*b = 222;     b = 222; 
qDebug("%d", *a);   qDebug("%d", (int) a); 

Обе программы печати 222. Для кода левой этого является то, что мы бы (синтаксис указателя - большой намек), но для правого кода это неприятный сюрприз. Явный обмен может решить проблему владения, но его вводящий в заблуждение синтаксис дискредитирует его как альтернативу указателям.

Qt-классы QMemArray, QImage и QMovie обязаны своим явным общим доступом к истории. Чтобы держать голову над водой, выберите одно из следующих правил при работе с явно разделяемыми классами:

Избегайте явных разделяемых классов. Вызов detach() каждый раз, когда вы собираетесь изменить объект, если только вы не уверены, что объект не имеет копии. Это сильно подвержено ошибкам. Вызов detach() каждый раз, когда вы делаете копию объекта: b = a; b.detach(); Это эффективно отключает совместное использование и означает, что в противном случае вам не нужно будет звонить detach(). Используйте функцию копирования(), если таковая имеется:

b = a.copy(); 
+0

Я довольно запутанный на самом деле ... Я хочу динамически добавлять точки к моему вектору и избегать ВСЕ ТИПОВ копирования, и когда я добавляю точку, я хочу автоматически увидеть ее эффект на сюжете! что бы вы посоветовали в этом случае? –

+0

Это в основном означает, что он не сделает копию, она примет фактическую переменную. Если вам нужно немедленно его увидеть, вызовите любую функцию обновления для графика после добавления точки. – chris

+1

@chris Не похоже на это. См. Мой ответ для исследования исходного кода ... это может быть устаревший комментарий, который не был синхронизирован (?). Разговор об этом здесь: http://comments.gmane.org/gmane.comp.graphics. qwt.general/3228 – HostileFork