显式共享是什么意思

What does explicitly shared mean?

本文关键字:意思 是什么 共享      更新时间:2023-10-16

在此页面中:

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

方法

void QwtPlotCurve::setRawSamples()

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

而:

void QwtPlotCurve::setSamples()

使用QVector,更方便。但它只是"明确共享"。那是什么意思?保存指针就像第一个一样吗?

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

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

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

自 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();