C++--this关键字

目录

1.this关键字的解释

2.this关键字的使用

2.1 访问当前对象的成员和解决命名冲突。

2.2  链式调用

3.this 关键字总结

3.1.常量指针

3.2.在静态成员函数中不可用

3.3 this指向

3.1. this 在继承关系中的指向

3.2. this 在派生类中的指向

3.3. 基类指针或引用访问基类成员


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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值