自引用:this
在每个类的上下文中,其方法代码中都存在一个特殊引用,指向当前对象本身:this.它本质上是一个隐式定义的变量。所有使用对象变量的方法也同样适用于 this。具体而言,您可以通过取消引用 this 来访问对象字段或调用某个方法。例如,在 Shape 类的一个方法中,以下两条语句是等效的(为方便演示,我们仅以 draw 方法为例):
class Shape
|
如果同一上下文内存在其他同名的变量或参数,可能需要使用长形式。虽然通常不建议这样做,但在必要时,this 关键字可让您引用对象的重写成员。
如果任何局部变量或方法参数的名称与类成员变量的名称重叠,则编译器会发出警告。
在以下假设示例中,我们实现了 draw 方法,该方法接受一个可选的字符串参数 backgroundColor,表示颜色名称。由于参数名称与 Shape 类成员同名,编译器会发出第一个警告“'backgroundColor’ 的定义隐藏了该字段”。
这种重叠的后果是,后面错误地赋值 clrBlue 时,实际操作的是参数而不是类成员。由于值和参数类型不匹配,编译器将发出第二个警告“数字到字符串隐式转换”(这里的数字是常量 clrBlue)。但是,this.backgroundColor = clrBlue 行将值写入对象的字段。
void draw(string backgroundColor = NULL) //warning 1:
|
随后(在嵌套的花括号块中)定义的局部布尔变量 backgroundColor 再次重写了之前对该名称的定义(这就是我们收到第三个警告的原因)。然而,通过取消引用 this,this.backgroundColor = clrRed 语句仍会引用对象字段。
如果没有指定 this,编译器会一律选择上下文中最接近的名称定义。
还有另一种需要使用 this 的情况:将当前对象作为参数传递给另一个函数。特别是,采用了一种方法,其中同一个类的对象负责创建/删除另一个类的对象,而从属对象必须知道其“上级”。然后,使用构造函数在“上级”类中创建从属对象,并将“上级”对象的 this 传递给它。这种技术通常使用动态对象分配和指针,因此 指针一节中显示了相关示例。
this 的另一个常见用途是从成员函数返回指向当前对象的指针。这使得我们可以链式调用多个成员函数。由于我们尚未深入学习指针,目前只需要了解,指向某个类对象的指针是通过在该类名后添加星号 * 来声明的,并且可以通过指针像直接操作对象一样对其进行操作。
例如,我们可以为用户提供几种单独设置形状属性的方法:更改颜色、水平或垂直移动。其中每个方法都将返回指向当前对象的指针。
Shape *setColor(const color c)
|
然后,可以方便地链式调用这些方法。
Shape s;
|
当一个类拥有大量属性时,这种方式能够让您以简洁且有选择性地配置对象。
在 类定义一节中,我们曾尝试记录一个对象变量,但发现只能在 Print 调用中使用其名称并加上 & 符号来获取一个指针,或者更确切地说,是一个唯一的数字标识符(句柄)。在对象上下文中,同样的句柄也可以通过 &this 来获取。
为了方便调试,您可以通过对象的描述符来识别对象。接下来我们将探讨类继承,尤其是存在多个类继承时,这种识别机制将非常有用。因此,在所有的构造函数和析构函数中,我们都添加(并且日后在派生类中也会添加)以下 Print 调用:
~Shape()
|
现在,所有创建和删除步骤都将在日志中标记上类名和对象编号。
我们在 Pair 结构体中实现了类似的构造函数和析构函数,但遗憾的是,结构体不支持指针,即无法写入 &this。因此,我们只能通过其内容(在本例中,是通过其坐标)来识别这些结构体:
struct Pair
|