有没有一种很好的测试方法来确保对象没有被复制?
您可以尝试以下检查:
现场演示
#include <boost/container/vector.hpp>
#include <iostream>
#include <ostream>
#include <vector>
#include <string>
using namespace boost;
using namespace std;
struct Test
{
bool copied;
Test()
: copied(false)
{
}
Test(const Test&)
: copied(true)
{
}
};
template<typename Container>
void check_move_constructor()
{
Container from(1);
Container to(boost::move(from));
cout << "\tmove constructor is" << (to[0].copied ? " not" : "") << " working" << endl;
}
template<typename Container>
void check_move_assignment()
{
Container from(1);
Container to;
to=boost::move(from);
cout << "\tmove assignment is" << (to[0].copied ? " not" : "") << " working" << endl;
}
template<typename Container>
void check_move(const string &name)
{
cout << name << " :" << endl;
check_move_constructor< Container >();
check_move_assignment< Container >();
cout << string(16,'_') << endl;
}
int main()
{
cout << boolalpha;
check_move< container::vector<Test> >("boost::container::vector");
check_move< vector<Test> >("std::vector");
return 0;
}
MSVC2008 输出:
boost::container::vector :
move constructor is working
move assignment is working
________________
std::vector :
move constructor is not working
move assignment is not working
________________
请注意,在这段代码中,我使用了从左值显式移动,因此复制省略在这里不起作用。
PS 另一种方法是检查生成的汇编代码。例如 MSVC 上的 /FA 编译器选项或 GCC 上的 -S。
您可以使用特殊函数调用标记感兴趣的地方:
__declspec(noinline) void asm_marker(int line) { volatile int i=line; };
#define ASM_MARKER asm_marker(__LINE__)
并将该标记放在代码中:
ASM_MARKER;
func_of_interest();
ASM_MARKER;
Asm 代码可能如下所示:
mov ecx, 235 ; 000000ebH
call ?asm_marker@@YAXH@Z ; asm_marker
mov edi, r12d
lea rcx, QWORD PTR [rdi+rdi*4]
mov rax, QWORD PTR vec$[rsp]
lea r9, QWORD PTR [rax+rcx*8]
mov rbx, QWORD PTR vec$[rsp+32]
mov ecx, 237 ; 000000edH
call ?asm_marker@@YAXH@Z ; asm_marker