2

在此页面中:

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

方法

void QwtPlotCurve::setRawSamples()

只是将数据的地址保存在 QwtPlotCurve 中,这正是我想要的效率。

尽管:

void QwtPlotCurve::setSamples()

使用QVector,更方便。但它只是“明确共享”。这意味着什么?是否像第一个一样保存指针?

我需要每 50 毫秒在图中添加一个点。深度复制数据不是最好的解决方案!!!建议?

4

2 回答 2

7

它与 Qt 的“隐式共享”概念并列:

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

即使你在 Qt 中按值传递一个 QVector 的数据作为参数,它也不会立即复制内存。如果其中一个向量发生更改,它只会制作副本。

我原以为在 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_xand的简单赋值d_y。这可以追溯到普通的 ol' 隐式共享。因此,您对传入的数据所做的更改将不会被绘图看到;您将支付进行此类修改时制作的副本的费用。

如果他们只是要这样做,那么为什么他们费心传递一个 const 引用(而不仅仅是通过值)对我来说是一个谜。这里唯一的“分享”似乎是隐含的,所以我不知道“明确分享”的评论应该是什么意思。

于 2012-04-21T15:12:48.117 回答
3

取自http://doc.qt.io/archives/qq/qq02-data-sharing-with-class.html

对于显式共享,在修改对象之前调用 detach() 是用户的责任,而不是类的责任。如果用户忘记调用 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()。如果可用,请使用 copy() 函数:

b = a.copy();
于 2012-04-21T15:08:28.707 回答