我很好奇其他人是如何使用这个关键字的。我倾向于在构造函数中使用它,但我也可能在整个类的其他方法中使用它。一些例子:
在构造函数中:
public Light(Vector v)
{
this.dir = new Vector(v);
}
在其他地方
public void SomeMethod()
{
Vector vec = new Vector();
double d = (vec * vec) - (this.radius * this.radius);
}
c++中还有一种用法没有提到,那就是不引用自己的对象,也不从接收到的变量中消除成员的歧义。
您可以使用它在从其他模板继承的模板类中将非依赖名称转换为依赖参数的名称。
template <typename T>
struct base {
void f() {}
};
template <typename T>
struct derived : public base<T>
{
void test() {
//f(); // [1] error
base<T>::f(); // quite verbose if there is more than one argument, but valid
this->f(); // f is now an argument dependent symbol
}
}
模板是用两遍机制编译的。在第一次传递过程中,只解析和检查非参数相关的名称,而仅检查相关名称的一致性,而不实际替换模板参数。
At that step, without actually substituting the type, the compiler has almost no information of what base<T> could be (note that specialization of the base template can turn it into completely different types, even undefined types), so it just assumes that it is a type. At this stage the non-dependent call f that seems just natural to the programmer is a symbol that the compiler must find as a member of derived or in enclosing namespaces --which does not happen in the example-- and it will complain.
解决方法是将非相关名称f转换为相关名称。这可以通过几种方式来实现,通过显式地声明它实现的类型(base<T>::f——添加base<T>使符号依赖于T,编译器只会假设它存在,并在参数替换后推迟第二次传递的实际检查。
第二种方法,如果你从有多个参数或长名称的模板继承,那就排序得更好,就是在符号前添加一个this->。因为你实现的模板类确实依赖于一个实参(它继承自base<T>) this->是实参依赖的,并且我们得到了相同的结果:this->f在模板形参替换之后的第二轮被检查。
这在c++编译器上
如果c++编译器没有立即找到一个符号,它会默默地查找。有时候,大多数时候,这是好的:
如果在子类中没有重载母类的方法,则使用母类的方法。
将一个类型的值提升为另一个类型
但有时候,你只是不想让编译器猜测。您希望编译器提取正确的符号,而不是其他符号。
对我来说,这些时候是在一个方法中,我想访问一个成员方法或成员变量。我只是不想因为我写了printf而不是print而随机抽取一些符号。这个->printf不会被编译。
关键是,对于C遗留库(§),多年前编写的遗留代码(§§),或者在复制/粘贴已经过时但仍然活跃的语言中可能发生的任何事情,有时,告诉编译器不要耍花招是一个好主意。
这就是我使用它的原因。
(§)这对我来说仍然是一个谜,但我现在想知道你在源代码中包含<windows.h>头的事实,是不是所有遗留的C库符号都会污染你的全局命名空间的原因
(§§)意识到“你需要包含一个头文件,但是包含这个头文件会破坏你的代码,因为它使用了一些具有通用名称的愚蠢宏”是程序员生活中的俄罗斯轮盘时刻之一