c++this指针

#define _CRT_SECURE_NO_WARNINGS

#include<iostream>
#include<vector>

using namespace std;

class AA
{
public:
    AA(int a, int b)
    {
        my_a = a;
        my_b = b;
    }
    int getA()//这儿相当于int getA(AA *this),this为指向对象的指针,只不过可以省略,编译器会自己帮我们添加
    {
        //下面一段代码等价于return this->my_a,this是一个指针,指向的就是创建的对象整体
        return my_a;
    }
private:
    int my_a;
    int my_b;
};

class Test
{
public:
    Test(int t)
    {
        //this指针是Test *const this(const看右面,离谁近就修饰谁),这表明指针this指向的空间内容可以修改,但指针本身不可以被修改,因此this是一个常指针,不可被修改
        this->my_t = t;
    }
    int getT() const//函数后面加const关键词修饰的是this指针,虽然this指针被隐藏了,函数从来不会被const修饰,函数后面加const表示这个指针指向空间的内容也不能被修改了
    {
        //this->my_t = 199;这段代码是错误的,因为const修饰了this指针,使this指向空间的内容也不允许被修改了
        return this->my_t;
    }
    static void function()
    {
        //为什么静态函数只能调用静态变量的根本原因L:
        //因为静态方法中不存在隐式的this指针,它不属于某个对象,它属于一个类,属于这个类的所有对象
    }
    
private:
    int my_t;
};

class Group
{
public:
    Group(int a, int b)
    {
        this->a = a;
        this->b = b;
    }
    int getA()
    {
        //类中的方法关于类内部变量的调用尽量用this表示,这样会增加代码的可读性,加this的一看就知道调用的变量是在类的内部的
        return this->a;
    }
    int getB()
    {
        return this->b;
    }
    //因为已经创建了对象,要依赖对象再建另外一个对象,这是没有办法直接使用构造函数建立的,只能使用成员方法进行,再成员方法里在调用构造函数创建新的对象
    Group groupAdd(Group &another)
    {
        //这里有两个对象,一个是调用这个方法的对象,this为其指针,一个是函数参数传进来的对象,another为其引用
        Group group(this->a + another.a, this->b + another.b);//因为在相同类的内部,所以可以直接调用私有变量
        return group;//这里应也是返回匿名对象
    }
    //返回对象的本身,其实这个对象内容本来已经被修改过了,并不需要返回干什么,但是为了可以直接实现连加,即出现+=的效果,所以需要返回对象本身
    //返回对象本身,一定只能用引用
    Group &groupSelf(Group &another)
    {
        this->a += another.a;
        this->b += another.b;
        return *this;//return *this指返回this指针指向区域的内容,即返回对象本身,如果return this则表明返回的是对象的指针,需要用对象的指针去接收,应也可以实现连加效果,但此时不是返回对象本身可,而是返回对象的指针
    }
    void printG()
    {
        cout << "a=" << a << endl;
        cout << "b=" << b << endl;
    }
private:
    int a;
    int b;
};

//全局函数,使对象g1和g2相加生成另一个对象
Group groupAdd(Group &g1, Group &g2)
{
    //调用显式构造函数,创建对象g3,里面的参数为对象g1和g2相加
    Group g3(g1.getA() + g2.getA(), g1.getB() + g2.getB());

    return g3;//这里是调用拷贝构造函数,返回了一个匿名对象,并不是对象g3
}

int main()
{
    AA a1(1, 2);//调用构造函数也是一样,编译器会自动帮我们把a1的地址传给构造函数,即等价于AA(&a1, 1, 2),所以初始化的数据一定只会传给对象a1
    AA a2(2, 3);

    //方法不是存在对象内部空间的,那么为什么a1.getA()返回的是对象a1的变量my_a而不是对象a2的变量my_a
    //因为下面一段代码a1.getA()等价于getA(&a1),是把对象a1的地址传给了函数,因此一定不会返回错误
    //总结:对象在调用方法时,不论是普通函数还是构造函数,都会隐式的把存有自己地址的指针传递进去,这样可以使方法唯一确定执行操作的位置
    a1.getA();

    Group g1(1, 2);
    Group g2(3, 4);
    //使用类外部的全局函数进行创建
    Group g3 = groupAdd(g1, g2);
    //对象调用内部方法构建另一个对象
    Group g4 = g1.groupAdd(g2);

    //下面一段代码的过程为:函数groupAdd()通过参数创建一个新的对象,这个对象再返回的时候会被调用拷贝构造函数构造一个匿名对象,然后这个对象被回收,匿名对象被返回,匿名对象再调用getA()方法获得匿名对象里私有成员a的值
    //返回引用时,引用的变量没被回收时可以做左值的,被回收是不能做左值的
    //一般变量被返回时,不会也没有拷贝构造匿名对象,直接用来赋值就可以,赋值完以后变量就会被回收
    int a = groupAdd(g2, g3).getA();//方法一定不能忘记()括号,不然会报错误


    Group g5(1, 1);
    Group g6(1, 1);

    //下面四段代码都可以实现连加效果,但前两段代码每次都会新建一个匿名对象,最后返回的是最后一个创建的匿名对象,这个匿名对象把前几个对象的值都加起来了
    Group g7 = g5.groupAdd(g1).groupAdd(g2).groupAdd(g3);
    g7.printG();
    //下面两段代码也可以实现连加效果,但这不会创建匿名对象,且结果都是存储在主对象g5中的,每次都会返回g5对象本身,在把g5和参数对象传进去,实现连加效果,即+=
    g5.groupSelf(g1).groupSelf(g2).groupSelf(g3);
    g5.printG();


    //only test,please ignore
    /*
    int nums[100];
    int b = sizeof(nums);//sizeof计算出来的是整个数组占多少,即100*int;
    cout << "sizeof=" << b << endl;
    vector<int> nums(10);
    int c = sizeof(nums);//但容器的大小不可以用sizeof计算,应用nums.size()计算,计算出来的结果是这个容器中含有多少个元素,即元素个数
    cout << "sizeof=" << c << endl;
    for (int i=0; i < 10; i++)
    {
        if (i <= 0)
        {
            cout << "============================" << endl;
            break;
        }
    }
    /*
    int c;
    vector<int> nums(10);
    cout << "sizeof=" << nums.size() << endl;
    char s[] = "hello";
    cout << "strlen=" << strlen(s) << endl;//结果为5,不算\0的位置
    cout << "sizeof=" << sizeof(s) << endl;//结果为6,算\0的位置
    const char *str = "hello";
    char buf[64] = "hello";
    if (strcmp(str, buf) == 0)//是相等的
    {
        cout << "==============================" << endl;
    }
    */
    return 0;
}
### C++ 中 `this` 指针的概念 在 C++ 编程语言中,`this` 是一个特殊的指针变量,在类的非静态成员函数内部自动存在。它指向当前正在被操作的对象实例[^1]。通过使用 `this` 指针,可以访问对象的数据成员以及成员函数。 #### 为什么需要 `this` 指针? 当在一个类的方法中定义了一个局部变量或者参数名与数据成员同名时,可能会发生命名冲突。此时可以通过 `this->` 来区分它们,其中 `this` 明确表示的是当前对象的数据成员[^2]。 --- ### `this` 指针的主要用途 以下是几种常见的场景下 `this` 的应用方式: #### 1. 解决名称冲突 如果某个方法接收的参数名字与其所属类中的成员变量相同,则可以用 `this` 指向实际的成员变量来消除歧义。 ```cpp #include <iostream> using namespace std; class Person { private: string name; public: void setName(string name) { this->name = name; // 使用 this 区分成员变量和形参 } void getName() const { cout << "Name is: " << name << endl; } }; int main(){ Person p; p.setName("Alice"); p.getName(); return 0; } ``` 上述例子展示了如何利用 `this` 避免因重名而产生的混乱情况。 #### 2. 返回当前对象本身 返回 *current object* 可用于链式调用(chaining),即连续执行多个操作于同一个对象之上而不需重复指定目标实体。 ```cpp class Counter{ private: int count; public: Counter():count(0){} Counter& increment(){ ++count; return *this; // 返回自身的引用以便支持连贯调用 } void displayCount()const{ cout<<"Current Count:"<<count<<endl; } }; // 测试部分省略... ``` 这里展示了一种模式——允许像这样写代码:`counter.increment().increment()`[^3]。 #### 3. 调用其他成员函数 有时候可能希望从某成员函数内部去触发另一个成员函数的动作;这时就可以借助 `this` 实现这一点。 ```cpp void bar() { std::cout << "Inside bar()" << std::endl; this->foo(); // 利用 this 呼叫另一项功能 } ``` 此片段取自先前提供的资料说明了怎样借由 `this` 执行额外的功能呼叫。 #### 4. 动态分配内存给对象副本 另外一种常见情形是在构造器里复制传入的对象属性值到新建立出来的个体之中,这时候也可以运用 `this`. ```cpp Person(const Person &other){ *(this)= other;// 将 another 对象的内容赋值给自己 } ``` 注意这里的语法结构意味着把右侧表达式的全部字段逐一对应拷贝至左侧所代表的新建体当中[^4]。 --- ### 总结注意事项 尽管 `this` 提供了许多便利之处,但也有一些地方值得特别留意: - 它仅存在于非静态成员函数之内; - 不可手动修改其地址值; - 当涉及多线程环境下的共享资源管理时要格外小心同步问题等等。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值