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

猜你喜欢

转载自blog.csdn.net/tulipless/article/details/80542148
今日推荐