2012-04-21 34 views
2

在這個頁面:明確共享是什麼意思?

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

的方法

void QwtPlotCurve::setRawSamples() 

只是保存在QwtPlotCurve,這正是我想要的效率數據的地址。

雖然:

void QwtPlotCurve::setSamples() 

使用QVector,這是更方便的。但它只是「明確共享」。那是什麼意思?像第一個那樣保存指針?

我需要每50毫秒添加一個點到繪圖。數據的深度複製並不是最好的解決方案!建議?

+0

50毫秒通常是足夠長的時間做了一大堆的東西。 – 2012-04-21 15:20:21

回答

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 
) 

而且我也想到他們這樣做,這樣,如果你改變你的矢量數據(或免費的話),這樣會影響扶住由情節曲線的數據。如果您認爲這些媒介是按照價值傳遞的(您無法判斷您是否正在閱讀調用網站),您不會期望這一點。

無論其看着似乎在引擎蓋下,它只是做一個隱式共享副本反正源代碼。在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_xd_y。這可以追溯到普通的「隱性共享」。所以,改變了你在你通過將由圖中可以看到的數據做;您將支付此修改時的副本。

如果他們只是要做到這一點,那麼爲什麼他們困擾傳遞一個const引用(而不是隻是值)是一個謎給我。在這裏進行的唯一「共享」似乎是隱含的,所以我不知道「明確共享」評論應該是什麼意思。

+0

這是否意味着如果我添加一個指向數組XDATA,YDATA,我會看到它立即對情節的影響?這正是我想要的!!!!!!!!!我打算使用像FIFO這樣的東西來繪製我添加到這些數組中的點。這是我在找什麼? – 2012-04-21 15:23:48

+0

我查看了代碼,答案是否定的。查看更新。 – HostileFork 2012-04-21 15:39:50

+0

如果您對載體進行了較小的修改並希望避免複製,您可以嘗試類似於'myPlot-> setSamples(QVector (),QVector ());'* *之前*您做任何更改你傳入的矢量。這將讓情節釋放它所持有的隱式共享引用,所以你不必爲修改時發生的副本付費。可以幫助... [聳肩] – HostileFork 2012-04-21 16:01:05

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

我很困惑其實......我想動態添加點到我的矢量和避免複製的所有類型,當我補充一點,我想自動看到其對劇情的影響!在這種情況下你會建議什麼? – 2012-04-21 15:27:30

+0

它基本上意味着它不會複製,它將採用實際變量。如果您需要立即查看,請在添加點後調用任何更新函數。 – chris 2012-04-21 15:32:52

+1

@chris似乎並非如此。查看我對源代碼調查的回答......它可能是一個過時的未被同步的評論(?)關於此的對話:http://comments.gmane.org/gmane.comp.graphics。 qwt.general/3228 – HostileFork 2012-04-21 15:46:20