我刚刚与我的cpp导师进行了激烈的讨论,讨论如何使用this->
与“只是名字”来进行成员变量访问。
class Test{
int a;
int data[50000000];
int b;
Test(int c,int d){
a=c; //or this->a=c;
b=d; //or this->b=d;
}
};
他的理解是,纯名称表示对成员变量的引用,而使用this->
会扩展为(*this).
,我同意后者。
出于性能原因,您将使用对变量的引用,因为延迟访问指针会将整个对象复制到适当位置,然后才访问一部分。由于这种情况曾经发生在this->
上,因此会对性能产生很大的影响。
但是我已经尝试过将两个版本都翻译成程序集,并且没有区别。这是为什么? (我不习惯集会来理解整个上下文,所以我不知道)
在这种情况下,编译器是否不使用引用,而是使用更类似于取消引用的内容,还是只是不进行我期望它执行的操作? (如果有的话,我们一直在谈论c ++ 11)
答案 0 :(得分:0)
在带和不带this->
的情况下访问非静态成员函数中的成员将导致相同的机器代码。后者是前者的语法糖。代码
class A {
public:
int a;
A() {
a = 1;
}
};
class B {
public:
int b;
B() {
this->b = 1;
}
};
int main() {
A a;
B b;
return 0;
}
无需优化即可翻译为
main: # @main
push rbp
mov rbp, rsp
sub rsp, 16
mov dword ptr [rbp - 4], 0
lea rdi, [rbp - 8]
call A::A() [base object constructor]
lea rdi, [rbp - 16]
call B::B() [base object constructor]
xor eax, eax
add rsp, 16
pop rbp
ret
A::A() [base object constructor]: # @A::A() [base object constructor]
push rbp
mov rbp, rsp
mov qword ptr [rbp - 8], rdi
mov rax, qword ptr [rbp - 8]
mov dword ptr [rax], 1
pop rbp
ret
B::B() [base object constructor]: # @B::B() [base object constructor]
push rbp
mov rbp, rsp
mov qword ptr [rbp - 8], rdi
mov rax, qword ptr [rbp - 8]
mov dword ptr [rax], 1
pop rbp
ret
取消引用指针不会复制对象,但会产生对该对象的引用。否则类似
int a(0);
int pa = &a;
*pa = 12;
std::cout << a << '\n'; // prints 12
将无法按预期工作。同样,此访问通过引用进行:
class A {
public:
int a(0);
int b(0);
int c(0);
A() {
a = 1;
this->b = 2;
(*this).c = 3;
std::cout << a << " " << b << " " << c << '\n'; // prints 1 2 3
}
};
如果它是副本,则无法设置成员变量的值。每次您更改原点的值时,它都是参考,而不是副本。