-2

我有以下代码行

#include <stdio.h>
#include <utility>

class A
{
    public: // member functions
        explicit A(int && Val)
        {
            _val = std::move(Val); // \2\
        }
        virtual ~A(){}

    private: // member variables
        int _val = 0;

    private: // member functions
        A(const A &) = delete;
        A& operator = (const A &) = delete;
        A(A &&) = delete;
        A&& operator = (A &&) = delete;
};


int main()
{
    A a01{3}; // \1\
    return 0;
}

我想问我从\1\到制作了多少份\2\

4

2 回答 2

1

您的代码无法编译,但在对其进行编译所需的更改后,它什么也不做并编译到这个 x86 程序集中,因为它的任何值都没有被使用过:

main:
  xor eax, eax
  ret

https://godbolt.org/z/q70EMb

修改代码使其需要_val成员变量的输出(使用 print 语句)表明,通过优化它只需将值移动0x03到寄存器中并打印它:

.LC0:
  .string "%d\n"
main:
  sub rsp, 8
  mov esi, 3
  mov edi, OFFSET FLAT:.LC0
  xor eax, eax
  call printf
  xor eax, eax
  add rsp, 8
  ret

https://godbolt.org/z/JG73Ll

如果您禁用优化以试图让编译器输出更详细的程序版本:

A::A(int&&):
  push rbp
  mov rbp, rsp
  sub rsp, 16
  mov QWORD PTR [rbp-8], rdi
  mov QWORD PTR [rbp-16], rsi
  mov rax, QWORD PTR [rbp-8]
  mov DWORD PTR [rax], 0
  mov rax, QWORD PTR [rbp-16]
  mov rdi, rax
  call std::remove_reference<int&>::type&& std::move<int&>(int&)
  mov edx, DWORD PTR [rax]
  mov rax, QWORD PTR [rbp-8]
  mov DWORD PTR [rax], edx
  nop
  leave
  ret
.LC0:
  .string "%d\n"
main:
  push rbp
  mov rbp, rsp
  sub rsp, 16
  mov DWORD PTR [rbp-4], 3
  lea rdx, [rbp-4]
  lea rax, [rbp-8]
  mov rsi, rdx
  mov rdi, rax
  call A::A(int&&)
  mov eax, DWORD PTR [rbp-8]
  mov esi, eax
  mov edi, OFFSET FLAT:.LC0
  mov eax, 0
  call printf
  mov eax, 0
  leave
  ret
std::remove_reference<int&>::type&& std::move<int&>(int&):
  push rbp
  mov rbp, rsp
  mov QWORD PTR [rbp-8], rdi
  mov rax, QWORD PTR [rbp-8]
  pop rbp
  ret

https://godbolt.org/z/ZTK40d

您的问题的答案取决于您的程序是如何编译的以及如何强制执行复制省略,以及在int不“复制”值的情况下是否有任何好处,因为int*并且int可能占用相同数量的记忆。

于 2018-10-04T06:50:43.763 回答
0

您只是分配一个值,而不是复制。不过,您可以在您的类中拥有一个静态成员,每次调用此方法时该成员都会递增!

class A
{

    public: // member functions
        static int counter = 0;
        explicit A(int && Val)
        {
            _val = std::move(Val); // \2\
            counter++;
        }
        ....
于 2018-10-04T06:48:40.307 回答