C++学习之this指针和常成员函数

  1. this指针
    1)类中的成员函数(包括构造函数、析构函数)中都隐藏一个该类类型指针参数,名为this;在成员函数中访问类中的其它成员,其本质都是this来实现的。
    2)对于普通成员函数,this指向调用对象的地址;如果对于构造函数,this指向正在创建的对象地址。
    3)大多数情况可以忽略this,在成员函数宏直接访问类中的其它成员,但是以下几个特殊场景必须要使用this指针:
     
    –》区分作用域

    #include <iostream>
    using namespace std;
    class Teacher{
    public:
        /*
        Teacher(const string&name,int age,double sal)
            :m_name(name),m_age(age),m_sal(sal){
            cout << "构造函数:" << this << endl;    
        }*/
        //当参数变量和成员变量名字相同时,可以通过
        //this区分,通过this所访问到的一定是成员变量
        Teacher(const string& m_name,int m_age,
                double m_sal){
            this->m_name = m_name;
            this->m_age = m_age;
            this->m_sal = m_sal;
        }
        void print(void){
            cout << m_name << "," << m_age << 
                "," << m_sal << endl;
            cout << this->m_name << ","<< this->m_age
                << "," << this->m_sal << endl;
        }/*编译器处理后:
        void print(Teacher* this){
            cout << this->m_name << ","<< this->m_age
                << "," << this->m_sal << endl;
        }*/
    private:
        string m_name;
        int m_age;
        double m_sal;
    };
    int main(void){
        Teacher t1("张三",45,8000);
        Teacher t2("李四",46,9000);
        t1.print();//Teacher::print(&t1)
        t2.print();//Teacher::print(&t2)
    
        cout << "&t1=" << &t1 << endl;
        cout << "&t2=" << &t2 << endl;
    
        return 0;
    }
    

     
    –》从成员函数返回调用对象自身(返回自引用)

    #include <iostream>
    using namespace std;
    class Counter{
    public:
        Counter(int count=0):m_count(count){}
        Counter& add(void){
            ++m_count;
            //this指向调用对象,*this就是调用对象自身
            return *this;//返回自引用
        }
        void print(void){
            cout << "计数值:" << m_count << endl;
        }
    private:
        int m_count;
    };
    int main(void){
        Counter c;
        c.add().add().add();
        c.print();//3
        return 0;
    }
    

    注:上述代码中,add函数返回一定要是引用,如果返回不是引用而是对象则下:
    c.add().add().add()的调用过程为,c先调用一次add(),然后add代码中执行到return *this时,发生拷贝构造,将新复制出来的对象返回,然后新复制出来的对象调用这个第二个add(),同理,第二个add()在返回时,先将要返回的对象拷贝,然后返回这个新拷贝出来的对象,然后这个对象再执行第3个add(),所以,总的来说就是,有3个对象分别执行了一个一次add,3个对象中的m_count值分别为1,2,3,在返回对象而不是引用的情况下,增加如下代码验证第3个是3Counter c2 = c.add().add().add(); c2.print();会发现成c2的打印结果为3
    –》从类的内部销毁对象自身(对象自销毁) delete this;
    –》作为成员函数的实参,实现不同对象之间的交互

    #include <iostream>
    using namespace std;
    class Student;//短视声明
    class Teacher{
    public:
        void educate(Student* s);
        void reply(const string& answer);
    private:
        string m_answer;
    };
    class Student{
    public:
        void ask(const string& q,Teacher* t);
    };
    void Teacher::educate(Student* s){
        //通过this指针,将教师对象地址传给学生对象
        s->ask("什么是this指针?",this);//1)
        cout << "学生回答:" << m_answer << endl;//5)
    }
    void Teacher::reply(const string& answer){
        m_answer = answer;//4)
    }
    void Student::ask(const string& q,Teacher* t){
        cout << "问题:" << q << endl;//2)
        t->reply("this就是指向调用对象的地址");//3)
    }
    int main(void){
        Teacher t;
        Student s;
        t.educate(&s);
        return 0;
    }
    
  2. 常成员函数
    1)在一个成员函数参数表的后面加const,这个成员函数就是常成员函数(常函数).
    返回类型 函数名(形参表) const {函数体}
    2)常成员函数中this指针是一个常指针,不能在常成员函数中直接修改成员变量的值。
    注:可以在常成员函数中强转this来修改成员或者被mutable修饰的成员变量,可以在常成员函数直接修改
    3)非常对象既可以调用非常函数也可以调用常函数;但是常对象只能调用常函数,不能调用非常函数
    注:常对象也包括常指针和常引用

    #include <iostream>
    using namespace std;
    class A{
    public:
        //void func1(const A* this)
        void func1(void) const {
            cout << "常函数" << endl;
            //func2();//this->func2()
        }
        //void func2(A* this)
        void func2(void){
            cout << "非常函数" << endl;
        }
    };
    int main(void){
        A a;
        a.func1();//A::func1(&a),A*
        a.func2();//A::func2(&a),A*
        const A a2 = a;
        a2.func1();//A::func1(&a2),const A*
        //a2.func2();//A::func2(&a2),const A*
    
        const A* pa = &a;//pa:常指针
        pa->func1();
        //pa->func2();
        
        const A& ra = a;//ra:常引用
        ra.func1();
        //ra.func2();
    
        return 0;
    }
    

    4)同一个类中,函数名和参数表相同的成员函数,其常版本和非常版本可以构成有效的重载关系;常对象匹配常版本,非常对象匹配非常版本。

    #include <iostream>
    using namespace std;
    class A{
    public:
        void func(void)const{
            cout << "func常版本" << endl;    
        }
        void func(void){
            cout << "func非常版本" << endl;
        }
    };
    int main(void){
        A a;
        a.func();//非常版本
        const A a2 = a;
        a2.func();//常版本
        return 0;
    }
    
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值