使用Rvalue引用和Simple Factory
Using Rvalue references and Simple Factory
我最近了解了std::move
和rvalue
引用,想知道我对它们的使用是否既合适又有效。
考虑这个简单的Image
类,它简单地存储表示像素的unsigned char
值的数组。(注意,事实上,成员比单个字符数组多,但为了可读性,我在这里进行了简化。)
using PixelContainer = std::vector<unsigned char>;
class Image {
public:
Image(PixelContainer&& pixels) : m_pixels(std::move(pixels)) {};
Image& operator=(Image&& image) { m_pixels = std::move(image.m_pixels); return *this; };
private:
PixelContainer m_pixels;
};
现在考虑ImageFactory
类的这个静态方法,它接受.png
的文件名,并返回一个填充了适当像素值的Image
对象。
Image ImageFactory::loadImage(const char* filename) {
PixelContainer temp_pixels;
// ... fill pixels from file (details not relevant here)
Image temp_image(std::move(temp_pixels));
return temp_image;
}
最后,它们一起用于代码中,如下所示:
Image image = ImageFactory::loadImage("image.png");
我使用rvalue
引用来消除复制可能是一个大像素值数组所花费的时间。因为工厂创建的矢量和图像是临时的,所以它们可以四处移动。
我的问题是,我的实现有意义吗?如果它没有根本性的缺陷,它能进一步改进吗?
让我们来了解一下!我添加了一个这样的函数来包含你的最后一段代码:
Image outer() {
Image image = ImageFactory::loadImage("image.png");
return image;
}
我还必须为Image
添加一个常规的复制构造函数(我使用= default
来定义它),因为即使它实际上没有使用,它也需要按值返回。
然后我用Clang-O2-g-S编译,并查看组装。它主要是初始化矢量的代码:调用operator new
并设置矢量的内部指针。没有复制,代码看起来相当干净高效。正如您所希望的,outer()
的代码与loadImage()
的代码几乎相同(后者被内联到前者中,因为我将所有内容都放在一个翻译单元中)。
作为参考,这是我得到的组件:
outer(): ## @_Z5outerv
pushq %rbp
movq %rsp, %rbp
pushq %rbx
pushq %rax
movq %rdi, %rbx
movl $100000000, %edi ## imm = 0x5F5E100
callq operator new(unsigned long)
movd %rax, %xmm0
movlhps %xmm0, %xmm0 ## xmm0 = xmm0[0,0]
movq $-100000000, %rcx ## imm = 0xFFFFFFFFFA0A1F00
movq %rax, %rsi
LBB1_1: ## =>This Inner Loop Header: Depth=1
testq %rsi, %rsi
movl $0, %edx
je LBB1_3
movb $0, (%rsi)
movaps %xmm0, %xmm1
punpckhqdq %xmm1, %xmm1 ## xmm1 = xmm1[1,1]
movd %xmm1, %rdx
LBB1_3: ## %_ZNSt3__116allocator_traits...
incq %rdx
movd %rdx, %xmm1
punpcklqdq %xmm1, %xmm0 ## xmm0 = xmm0[0],xmm1[0]
incq %rcx
movq %rdx, %rsi
jne LBB1_1
## BB#4: ## %_ZN12ImageFactory9loadImageEPKc.exit
leaq 100000000(%rax), %rax
movdqu %xmm0, (%rbx)
movq %rax, 16(%rbx)
movq %rbx, %rax
addq $8, %rsp
popq %rbx
popq %rbp
retq
相关文章:
- 为什么别名声明不是有效的 init 语句(/simple-declaration)?
- 如何让"factory function"返回不可复制的对象?
- SImple 代码在 DevC++ 中正确运行,但不能在 Visual Studio Code 中正常运行
- 使用 clang 和 G++ 编译此"simple"程序时出现链接错误
- boost::shared_ptr in a modified factory method
- "simple" C++ 解析器
- 带有抽象类的unique_ptr成员和Copy构造函数的Factory方法模式
- C++ - Simple SharedQueue 是必需的
- 我们是否需要为分配"placement new" "simple POD classes"显式调用析构函数?
- 以"simple c++"模式编译的程序在从QtCreator启动时不起作用
- C Simple RingBuffer语言 - 多线程 - 查找关键部分
- Simple auto_ptr
- 如何指定factory对象的类型
- Simple C++ getter/setters
- CMake "clang++ is not able compile a simple test program" (Fedora 20)
- 使用Rvalue引用和Simple Factory
- C++ - Noob - Simple Try/Catch
- C++ Simple cout ostream
- 用基类模板化的静态方法(aka.Factory)派生类
- C++查找和替换字符串SIMPLE