首先奉上源代码
class A{
private:int i;
public:A() {std::cout << "default constructor is called" << std::endl;i = 0;}A(int _i): i(_i) {}A(const A& obj) {std::cout << "copy constructor is called" << std::endl;i = obj.i;}A& operator = (const A& obj) {std::cout << "assignment constructor is called" << std::endl;i = obj.i;return *this;}A (const std::initializer_list<int>& l) {std::cout << "initializer_list constructor is called" << std::endl;i = *(l.begin());}int get()const {return i;}void set(int j) {i = j;}
};void foo(A a){a.set(0xFF);}int main() {A a(3);foo(a);return 0;}
对于main函数中foo(a)这个函数调用,生成的汇编如下:
45 foo(a);0x00005562b9bc5219 <+44>: lea rdx,[rbp-0x10]0x00005562b9bc521d <+48>: lea rax,[rbp-0xc]0x00005562b9bc5221 <+52>: mov rsi,rdx0x00005562b9bc5224 <+55>: mov rdi,rax0x00005562b9bc5227 <+58>: call 0x5562b9bc52d6 <A::A(A const&)>0x00005562b9bc522c <+63>: lea rax,[rbp-0xc]0x00005562b9bc5230 <+67>: mov rdi,rax0x00005562b9bc5233 <+70>: call 0x5562b9bc51c9 <foo(A)>
从以上汇编可以明显看到,如果foo()的形参是一个值类型的话,首先调用copy构造函数生成一个实参对象的副本,然后把这个副本的地址传递给函数调用,记住,是副本的地址!