QPainter怎么转? (从工厂函数中移动一个对象)
How to transfer QPainter? (move an object from a factory function)
在一个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 引用,但这会降低方法的意义,并会增加调用者代码的干扰。
- 它可以 return
unique_ptr
到 QPainter
,但它会引入堆分配的开销。
- ...还有其他想法吗?
感谢您的回复!
一个技巧是通过常量引用return:
选项 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++ 标准,这保证不会发生复制,但 return 值的寿命会延长。
选项 2:
用户共享或独有的指针。我知道你说他们有开销,但这没什么,假设你不是在开发游戏引擎并且这是主要管道(而且我确定你没有在这样的游戏引擎中使用 Qt)。
选项 3:
如果其中 none 个让您满意,我会建议我讨厌的解决方案,只是为了完整性。使用宏!
#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 解决方案,可以在不使对象成为常量的情况下延长对象的生命周期。
和想法一样
struct ColoredPainter : public QPainter {
ColoredPainter (device, color) : QPainter (device)
setBrush(color);
setPen(color);
};
...
ColoredPainter painter(m_Image, color);
但我不喜欢这个主意。看起来重复的代码部分看起来是一样的,但是把它放到独立的块中是没有意义的。这样的class甚至是函数都很难理解。
在一个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 引用,但这会降低方法的意义,并会增加调用者代码的干扰。
- 它可以 return
unique_ptr
到QPainter
,但它会引入堆分配的开销。 - ...还有其他想法吗?
感谢您的回复!
一个技巧是通过常量引用return:
选项 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++ 标准,这保证不会发生复制,但 return 值的寿命会延长。
选项 2:
用户共享或独有的指针。我知道你说他们有开销,但这没什么,假设你不是在开发游戏引擎并且这是主要管道(而且我确定你没有在这样的游戏引擎中使用 Qt)。
选项 3:
如果其中 none 个让您满意,我会建议我讨厌的解决方案,只是为了完整性。使用宏!
#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 解决方案,可以在不使对象成为常量的情况下延长对象的生命周期。
和想法一样
struct ColoredPainter : public QPainter {
ColoredPainter (device, color) : QPainter (device)
setBrush(color);
setPen(color);
};
...
ColoredPainter painter(m_Image, color);
但我不喜欢这个主意。看起来重复的代码部分看起来是一样的,但是把它放到独立的块中是没有意义的。这样的class甚至是函数都很难理解。