6

我正在测试我的容器包装器是否正确实现了 URef。我能想到的唯一明显的方法是尝试找出一种方法来检测物体是否已移动。

有没有一种很好的测试方法来确保对象没有被复制?还是有另一种方法来测试我想要什么?我更喜欢不需要修改我正在测试的类的解决方案。因为有几十个。

你能否提供更多关于你所拥有的信息?就像你的容器是什么,你如何使用它,你能不能修改它等等。也许你可以在不修改你的容器的情况下测试它,而是使用特殊的容器元素类型——它跟踪副本和移动。

几个不同的容器和一些独立的模板函数。大多数情况下,它是 STL 库类型(如 deque、list、map、set 等)的包装器。

4

2 回答 2

2

有没有一种很好的测试方法来确保对象没有被复制?

您可以尝试以下检查:

现场演示

#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   
于 2012-11-10T23:46:03.313 回答
1

false添加一个在构造对象时设置为的布尔字段。在移动构造函数和移动赋值运算符中,分配true给要从中移动的对象中的该字段。

于 2012-11-10T23:45:04.683 回答