如何转移QPainter? (从工厂函数移动对象)

时间:2017-09-05 07:39:08

标签: c++ qt c++11 move-semantics qpainter

在与Qt相关的代码中,我试图通过以下方法减少一些重复的行:

QPainter createPainter(const QColor& color)
{
  QPainter painter(&m_image);
  painter.setBrush(color);
  painter.setPen(color);
  return painter;
}

但明确删除了QPainter的复制文件。它应该不是c ++ 11中的问题,但遗憾的是它既不可移动。是这样的原因还是仅仅是API缺陷? 它是createPainter的一个很好的解决方案(除了提供move-ctor)吗?

  • 它可以接受QPainter引用,但这会降低方法的含义,并会给调用者的代码增加噪声。
  • 它可以向unique_ptr返回QPainter,但会为堆分配带来开销。
  • ......还有其他想法吗?

感谢您的回复!

2 个答案:

答案 0 :(得分:2)

一个技巧是通过不断的引用返回:

选项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解决方案,可以延长对象的生命周期,而不会使其成为常量。

答案 1 :(得分:0)

同样的想法

struct ColoredPainter : public QPainter {
ColoredPainter (device, color) : QPainter (device)
setBrush(color);
setPen(color);
};

...

ColoredPainter painter(m_Image, color);

但我不喜欢这个主意。看起来重复的代码部分看起来一样,但把它放到独立块是没有意义的。很难理解这种类甚至功能。