2012-04-21 87 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