目录
1.this关键字的解释
在 C++ 中,this
关键字是一个指针,指向当前对象的地址。它在类的成员函数中使用,提供了一种访问当前对象的方式。this
的类型是指向当前类类型的指针。例如,在类 MyClass中,this
的类型是 MyClass*
。
在类定义内部,this
指针实际上是在成员函数被调用时才会有意义。当你在成员函数中使用 this
,它指向的是调用该成员函数的具体对象.
下面是一个代码示例及解释:
class MyClass {
public:
int value;
MyClass(int v) : value(v) {}
void display() {
std::cout << "Value: " << this->value << std::endl; // this 指向当前对象
}
};
int main() {
MyClass obj(42); // 实例化对象 obj
obj.display(); // 这里调用 display(),this 指向 obj
return 0;
}
解释:
1.1 类的定义与实例化:
在定义类时,我们只是创建了一个模板,里面包含数据成员和成员函数,但这时并没有创建任何对象。只有在我们实例化该类时,才会创建具体的对象。例如:
MyClass obj; // 这里实例化了一个对象
1.2 成员函数的调用:
当你调用某个对象的成员函数时,编译器会隐式(当你调用一个成员函数时,编译器自动处理将调用该函数的对象的地址传递给 this
指针)地将该对象的地址传递给 this 指针。比如:
obj.display(); // 调用 display() 时,this 指向 obj
1.3 this 作用
在 display 函数内部,this 指针指向的是 obj,因此你可以通过 this->value 访问 obj 的成员变量。
2.this关键字的使用
2.1 访问当前对象的成员和解决命名冲突。
在成员函数中,this
指针允许你访问和修改当前对象的成员变量和成员函数。例如:
class MyClass {
public:
int value;
MyClass(int value) {
this->value = value; // 使用 this 指针来区分参数和成员变量
}
void display() {
std::cout << "Value: " << this->value << std::endl; // 通过 this 访问成员变量
}
};
可以通过 this
调用对象的其他成员函数:
//调用成员函数
class Example {
public:
void show() {
std::cout << "Show function called!" << std::endl;
}
void callShow() {
this->show(); // 使用 this 调用其他成员函数
}
};
2.2 链式调用
在某些情况下,this
可以用于支持链式调用(方法返回当前对象的引用):
class Example {
public:
int value;
Example& setValue(int value) {
this->value = value;
return *this; // 返回当前对象的引用
}
void printValue() {
std::cout << "Value: " << value << std::endl;
}
};
int main() {
Example example;
example.setValue(42).printValue(); // 链式调用
return 0;
}
3.this 关键字总结
3.1.常量指针
this 的类型是 ClassName* const,其中 ClassName 是类的名称。const 表示指针本身是常量,意味着你不能改变 this 指针指向的地址(即它始终指向调用该函数的对象)。
3.2.在静态成员函数中不可用
this
关键字只能在非静态成员函数中使用,因为静态成员函数(static)没有与之关联的对象。
3.3 this指向
3.1. this
在继承关系中的指向
- 说明:在继承关系中,
this
指针始终指向调用成员函数的对象。 - 例子:假设有一个基类
Base
和一个派生类Derived
,当你在Derived
中调用基类的方法时,this
仍然指向Derived
的对象。
#include <iostream>
using namespace std;
class Base {
public:
virtual void show() {
cout << "Base class show function" << endl;
}
};
class Derived : public Base {
public:
void show() override {
cout << "Derived class show function" << endl;
// 在派生类的 show 函数中,this 仍然指向 Derived 对象
cout << "this points to: " << this << endl;
Base::show(); // 调用基类的 show 函数
}
};
int main() {
Derived d;
d.show(); // 通过 Derived 类对象调用 show
return 0;
}
Derived
类继承了Base
类,并重写了show
方法。当调用d.show()
时,this
指向的是Derived
类的对象,即d
。即使我们在Derived
类中调用Base::show()
,this
依然指向Derived
类的对象,因为this
永远指向调用成员函数的对象。
3.2. this
在派生类中的指向
- 说明:当派生类的对象调用成员函数时,无论这个函数是在基类还是在派生类中定义的,
this
都会指向派生类的对象。 - 例子:如果在
Derived
类中重载了Base
类的某个成员函数,调用这个函数时,this
将始终指向Derived
类的实例。
class Base {
public:
void func(int a) {
// 基类的实现
}
};
class Derived : public Base {
public:
void func(double b) { // 这是重载,不是重写
// 派生类的实现
}
};
int main() {
Derived d;
d.func(5.0); // 调用的是 Derived 的重载版本
return 0;
}
3.3. 基类指针或引用访问基类成员
- 向上转型:这指的是将派生类对象赋值给基类指针或引用。虽然指针或引用是基类类型,但它们仍然指向派生类对象。
#include <iostream>
class Base {
public:
void show() {
std::cout << "Base show()" << std::endl;
std::cout << "this: " << this << std::endl;
}
};
class Derived : public Base {
public:
void show() {
std::cout << "Derived show()" << std::endl;
std::cout << "this: " << this << std::endl;
}
};
int main() {
Derived d;
Base* basePtr = &d; // 向上转型,基类指针指向派生类对象
basePtr->show(); // 调用 Base 的 show() 方法
d.show(); // 调用 Derived 的 show() 方法
return 0;
}
- 访问基类成员:你可以通过基类指针或引用访问基类的成员,但不能直接访问派生类特有的成员。
- 动态类型转换:如果你需要访问派生类的成员,可以使用
dynamic_cast
进行类型转换。
class Base {
public:
void baseFunction() {
std::cout << "Base function" << std::endl;
}
};
class Derived : public Base {
public:
void derivedFunction() {
std::cout << "Derived function" << std::endl;
}
};
int main() {
Derived d;
Base* basePtr = &d; // 基类指针指向派生类对象
basePtr->baseFunction(); // 可以访问基类的方法
// basePtr->derivedFunction(); // 错误:无法访问派生类特有的方法
return 0;
}
在上面的代码中,basePtr
是指向 Base
类型的指针,但它实际上指向的是 Derived
类的对象。你可以通过 basePtr
调用 Base
类中的 baseFunction
,但无法直接调用 Derived
类的 derivedFunction
,因为 basePtr
的类型是 Base
。
如果需要访问 Derived
类的成员,必须先将 basePtr
转换为 Derived*
,这可以通过 dynamic_cast
实现。
class Base {
public:
void baseFunction() {
std::cout << "Base function" << std::endl;
}
};
class Derived : public Base {
public:
void derivedFunction() {
std::cout << "Derived function" << std::endl;
}
};
int main() {
Derived d;
Base* basePtr = &d; // 基类指针指向派生类对象
// 使用 dynamic_cast 来访问派生类特有的方法
if (Derived* derivedPtr = dynamic_cast<Derived*>(basePtr)) {
derivedPtr->derivedFunction(); // 可以安全地访问派生类的方法
}
return 0;
}