在没有指针的情况下在 Qt 中移动语义?
Move semantics in Qt without pointers?
我有一个Qt项目,里面有一个Object,要复制很多次。因此我想添加移动语义。
#ifndef OBJECTTOCOPY_H
#define OBJECTTOCOPY_H
#include <QColor>
#include <QString>
#include <QDataStream>
namespace level_1 {
namespace level_2 {
class ObjectToCopy {
public:
explicit ObjectToCopy(const QString& _name = "", const QColor& colorBody = QColor() );
// MOVE
ObjectToCopy(ObjectToCopy && other);
static quint32 _valueInt32;
static quint16 _valueInt16;
QString _name;
QColor _colorBody;
private:
};
}
}
#endif // OBJECTTOCOPY_H
如何窃取成员变量的指针,因为它们不是指针?
ObjectToCopy::ObjectToCopy (ObjectToCopy&& other)
: _valueInt32( other._valueInt32 )
, _valueInt16( other._valueInt16 )
, _name( other._name )
, _colorBody( other._colorBody )
{
other._valueInt32 = 0;
other._valueInt16 = 0;
other.name.clear();
other._colorBody = QColor();
}
- 这对非指针有意义吗?
- 像 string.clear(); 这样重置 QString 可以吗?为垃圾收集器做标记?
- 如何重置 QColor 对象?
您正在寻找std::move:
ObjectToCopy::ObjectToCopy (ObjectToCopy&& other)
: _valueInt32( other._valueInt32 )
, _valueInt16( other._valueInt16 )
, _name( std::move(other._name) )
, _colorBody( std::move(other._colorBody) )
{
other._valueInt32 = 0; //probably not necessary
other._valueInt16 = 0; //probably not necessary
//other.name.clear(); //not necessary
//other._colorBody = nullptr; //not necessary
}
移动非指针是有意义的。你正在制作这样一个物体。移动整数无济于事,但也无妨,因此您也可以为了一致性而这样做。移动没有移动构造函数的东西也可以:如果没有可用的移动构造函数,则使用复制构造函数(移动并不总是更好,但也不总是更差)。
上面的实现说“通过复制 int
和移动 name
和 _colorBody
来移动”。
确保您没有从 move
d 来自的变量中读取。
可以,但没必要。 other
应该是临时的,无论如何都会被摧毁。 (C++ 没有你意义上的垃圾收集器)
此外,一旦某个对象 move
d 从它开始,它往往会像 QString
一样处于 clear
ed 状态,但情况并非总是如此。
你真的不能。您可以分配一个默认构造的 other._colorBody = QColor();
但这只是意味着它将颜色设置为黑色。 QColor
不能为空,它总有一些颜色。
另读What are move semantics?
您当然可以添加移动语义,但在您的情况下根本不需要这样做。 quint32, quint16 通过复制移动。 QColor 是 union 的包装器,没有移动构造函数(也不需要),也可以通过复制移动。 QString 是 QT 中的引用计数类型。它在最近版本的库中有移动构造函数,但速度差异很小(交换指针和递增引用计数器之间的差异)。
我有一个Qt项目,里面有一个Object,要复制很多次。因此我想添加移动语义。
#ifndef OBJECTTOCOPY_H
#define OBJECTTOCOPY_H
#include <QColor>
#include <QString>
#include <QDataStream>
namespace level_1 {
namespace level_2 {
class ObjectToCopy {
public:
explicit ObjectToCopy(const QString& _name = "", const QColor& colorBody = QColor() );
// MOVE
ObjectToCopy(ObjectToCopy && other);
static quint32 _valueInt32;
static quint16 _valueInt16;
QString _name;
QColor _colorBody;
private:
};
}
}
#endif // OBJECTTOCOPY_H
如何窃取成员变量的指针,因为它们不是指针?
ObjectToCopy::ObjectToCopy (ObjectToCopy&& other)
: _valueInt32( other._valueInt32 )
, _valueInt16( other._valueInt16 )
, _name( other._name )
, _colorBody( other._colorBody )
{
other._valueInt32 = 0;
other._valueInt16 = 0;
other.name.clear();
other._colorBody = QColor();
}
- 这对非指针有意义吗?
- 像 string.clear(); 这样重置 QString 可以吗?为垃圾收集器做标记?
- 如何重置 QColor 对象?
您正在寻找std::move:
ObjectToCopy::ObjectToCopy (ObjectToCopy&& other)
: _valueInt32( other._valueInt32 )
, _valueInt16( other._valueInt16 )
, _name( std::move(other._name) )
, _colorBody( std::move(other._colorBody) )
{
other._valueInt32 = 0; //probably not necessary
other._valueInt16 = 0; //probably not necessary
//other.name.clear(); //not necessary
//other._colorBody = nullptr; //not necessary
}
移动非指针是有意义的。你正在制作这样一个物体。移动整数无济于事,但也无妨,因此您也可以为了一致性而这样做。移动没有移动构造函数的东西也可以:如果没有可用的移动构造函数,则使用复制构造函数(移动并不总是更好,但也不总是更差)。
上面的实现说“通过复制
int
和移动name
和_colorBody
来移动”。确保您没有从
move
d 来自的变量中读取。可以,但没必要。
other
应该是临时的,无论如何都会被摧毁。 (C++ 没有你意义上的垃圾收集器)此外,一旦某个对象
move
d 从它开始,它往往会像QString
一样处于clear
ed 状态,但情况并非总是如此。你真的不能。您可以分配一个默认构造的
other._colorBody = QColor();
但这只是意味着它将颜色设置为黑色。QColor
不能为空,它总有一些颜色。
另读What are move semantics?
您当然可以添加移动语义,但在您的情况下根本不需要这样做。 quint32, quint16 通过复制移动。 QColor 是 union 的包装器,没有移动构造函数(也不需要),也可以通过复制移动。 QString 是 QT 中的引用计数类型。它在最近版本的库中有移动构造函数,但速度差异很小(交换指针和递增引用计数器之间的差异)。