QPainter如何传输? (从工厂函数中移动一个对象)
Posted
技术标签:
【中文标题】QPainter如何传输? (从工厂函数中移动一个对象)【英文标题】:How to transfer QPainter? (move an object from a factory function) 【发布时间】:2017-09-05 07:39:08 【问题描述】:在一个Qt相关的代码中,我尝试通过以下方法减少一些重复的行:
QPainter createPainter(const QColor& color)
QPainter painter(&m_image);
painter.setBrush(color);
painter.setPen(color);
return painter;
但是QPainter
的复制ctor 被明确删除。在 c++11 中应该不是问题,但遗憾的是它既不是可移动的。这是什么原因,还是只是 API 缺陷?
createPainter
是不是很好的解决方案(除了提供move-ctor)?
unique_ptr
返回到QPainter
,但会引入堆分配开销。
...还有其他想法吗?
感谢您的回复!
【问题讨论】:
为什么不使用指针?喜欢:QPointer *p = new QPainter(&m_image); ... return p;
?
我不想在堆上分配对象,只是为了提取三行代码。 (在那种情况下,我会使用智能指针确保在任何情况下都能正确释放画家)
如果您要转移对象的所有权或以其他方式处理它,使用智能指针是有意义的。我看你这里不需要它。不要以为使用“智能”指针会让你的代码更智能。
实际上返回的指针必须是delete
d 有一个名字:所有权转移。返回原始拥有指针很容易出错。这是类似 C 的方式,但在 C++ 中不是惯用的。
@titapo 检查我的编辑。它解决了你的问题。
【参考方案1】:
一个技巧是通过常量引用返回:
选项 1:
QPainter createPainter(const QColor& color) //definitely return by value
QPointer painter(&m_image);
painter.setBrush(color);
painter.setPen(color);
return painter;
然后这样做:
const QPainter& painter = createPainter(const QColor& color);
根据 C++ 标准,这保证不会发生复制,但会延长返回值的寿命。
选项 2:
用户共享或唯一指针。我知道你说他们有开销,但这没什么,假设你没有开发游戏引擎并且这是主要管道(我确定你没有在这样的游戏引擎中使用 Qt)。
选项 3:
如果这些都不能让你满意,我会建议我讨厌的解决方案,只是为了完整性。使用宏!
#define CreatePainter(painter_name) \
QPointer painter_name(&m_image); \
painter_name.setBrush(color); \
painter_name.setPen(color);
使用它:
CreatePainter(painter);
painter.begin();
//...
编辑:
选项 4: 我刚刚得知(感谢 Quentin)这是合法的:
QPainter createPainter(const QColor& color) //definitely return by value
QPointer painter(&m_image);
painter.setBrush(color);
painter.setPen(color);
return painter;
然后这个:
QPainter&& painter = createPainter(const QColor& color);
检查参考here。这是一个新的 C++11 解决方案,可以延长对象的生命周期而不使其成为 const。
【讨论】:
我喜欢选项 1!不幸的是,绘图是一个非常量操作,因此在当前情况下它不起作用。 @titapo 那么我要告诉你世界上最糟糕的建议:使用const_cast
(不!只是在开玩笑:))。我看到的唯一合法的解决方案是宏。
如果函数按值返回对象,如何避免复制(选项 1)?
@vahancho 自己试试。这是标准的一部分。人们因此多次攻击我,因为它非常不直观,但它存在于 C++ 中。它被一些“最重要的常量”调用。 Check this.
@TheQuantumPhysicist,我确实没有攻击你。刚问了一个问题。现在我也明白了,谢谢。【参考方案2】:
想法一样
struct ColoredPainter : public QPainter
ColoredPainter (device, color) : QPainter (device)
setBrush(color);
setPen(color);
;
...
ColoredPainter painter(m_Image, color);
但我不喜欢这个主意。看起来重复的代码部分看起来是一样的,但把它放到独立块中是没有意义的。这种类甚至函数都很难理解。
【讨论】:
以上是关于QPainter如何传输? (从工厂函数中移动一个对象)的主要内容,如果未能解决你的问题,请参考以下文章
使用 PySide 时,如何有效地将数据从 NumPy 数组传输到 QPolygonF?
如何使用 QPainter 在 QOpenGLWidget 中进行叠加 [关闭]
如何使用 QPropertyAnimation 和 QPainter 绘制弧线