一、this指针
1、C++类对象中的成员变量和成员函数是分开存储的。C语言中的内存四区模型仍然有效!
2、C++中类的普通成员函数都隐式包含一个指向当前对象的this指针。
3、静态成员函数、成员变量属于类
4、静态成员函数与普通成员函数的区别
静态成员函数不包含指向具体对象的指针,静态成员函数只能访问静态成员变量
普通成员函数包含一个指向具体对象的指针
this指针不是const Test *test; //this->a=100; 正确
this指针时一个常指针 是 Test * const test; //this++; 错误
二、const修饰成员函数 到底修饰谁
//1 const 写在哪个位置 没有关系
void OpVar(int a, int b) const 等价于 void const OpVar(int a, int b) 等价于 const void OpVar(int a, int b)
//2 const 修饰的是谁
//2-1 const 修饰的形参a 不是
//2-1 const 修饰的是属性this->a this->b
//2-3 const 修饰的是this指针所指向的内存空间 修饰的是this指针
//void OpVar(int a, int b) { //===>void OpVar(Test *const this,int a, int b)
void const OpVar(int a, int b) const { //===>void OpVar(const Test * const this,int a, int b) Test内存指向的空间不可更改
总结:类的成员函数尾部出现const修饰,修饰的是this指针,意思是不可更改this指针指向的内容
三、全局函数和成员函数的转换
1、把全局函数转化成成员函数,通过this指针隐藏左操作数
Test add(Test &t1, Test &t2)===》Test add(Test &t2)
2、把成员函数转换成全局函数,多了一个参数
void printAB()===》void printAB(Test *pthis)
四、函数返回元素和引用
如果相对一个对象连续调用成员方法,每次都会改变对象本身,成员方法需要返回引用
Test& add(Test &t2) //*this //函数返回引⽤
{
this->a = this->a + t2.getA();
this->b = this->b + t2.getB();
return *this; //*操作让this指针回到元素状态
}
Test add2(Test &t2) //*this //函数返回元素
{
//t3是局部变量
Test t3(this->a+t2.getA(), this->b + t2.getB()) ;
return t3;
}
this指针和const修饰函数应用举例:
#if 1
#include<iostream>
using namespace std;
class Test {
public:Test(int a, int b) { //--->Test(Test *this,int a,int b)this->a = a;this->b = b;}void printT() {cout << "a:" << a << endl;cout << "a:" << this->b << endl;}//1 const 写的是什么位置 没有关系//2 const 修饰的是谁//2-1 const 修饰的形参a 不是//2-1 const 修饰的是属性this->a this->b//2-3 const 修饰的是this指针所指向的内存空间 修饰的是this指针//void OpVar(int a, int b) const { //===>void OpVar(Test *const this,int a, int b) const void const OpVar(int a, int b) const { //===>void OpVar(const Test * const this,int a, int b) const Test内存指向的空间不可更改a = 100;//this->a = 100; 报错//this->b = 100;cout << a << endl;cout << b << endl;}
protected:
private:int a;int b;
};void main() {Test t1(1, 2);t1.printT(); //printT(&t1)cout << "hello" << endl;
}
#endif
全局函数和成员函数应用举例:
#if 1
#include<iostream>
using namespace std;
class Test
{
public:int a;int b;
public:Test(int a=0, int b=0) {this->a = a;this->b = b;}Test(int a) {this->a = a;this->b = 0;}Test TestAdd1(Test &t1) {/*Test t(0, 0);t.a = a + t1.b;t.b = b + t1.b;*/Test t(this->a + t1.a, this->b + t1.b);return t;}void TestAdd2(Test &t1) {this->a = a + t1.a;this->b = b + t1.b;}//返回一个引用 相当于返回变量自身Test& TestAdd3(Test &t1) {this->a = this->a + t1.a;this->b = this->b + t1.b;return *this; //相当于把*(&t1)又回到了t1元素}void printT() {cout << "a:" << a << endl;cout << "b:" << b<<endl;}~Test() {cout << "析构函数" << endl;}};
//把成员函数转换成 全局函数 多一个参数
void printT(Test *pT) {cout << "a:" << pT->a << endl;cout << "b:" << pT->b << endl;
}
//全局函数 转成 成员函数 少一个参数
Test TestAdd(Test &t1, Test &t2) {Test t(0,0);t.a = t1.a + t2.a;t.b = t1.b + t2.b;return t;
}
void test01() {Test t1(1, 2);Test t2(3, 4);Test t3;//全局函数方法t3= TestAdd(t1, t2);
}
/*
析构函数
析构函数
析构函数
析构函数
析构函数
*/
void test02() {Test t1(1, 2);Test t2(3, 4);{//成员函数方法Test t3 = t1.TestAdd1(t2); //匿名对象直接转化为t3t3.printT();Test t4;t4 = t1.TestAdd1(t2); //匿名对象复制给t4t4.printT();}t1.TestAdd2(t2);
}
/*
析构函数
a:4
b:6
析构函数
析构函数
a:4
b:6
析构函数
析构函数
析构函数
析构函数
*/
void test03() {Test t1(1, 2);Test t2(3, 4);//t2=t2+t1;t2.TestAdd2(t1);t2.printT();t2.TestAdd3(t1);t2.printT();
}
/*
a:4
b:6
a:5
b:8
析构函数
析构函数
*/
int main() {//test01();//test02();test03();return 0;
}
#endif
函数返回引用和元素示例:
#if 1
#include<iostream>
using namespace std;
class Test
{
public:int a;int b;
public:Test(int a = 0, int b = 0) {this->a = a;this->b = b;}Test(int a) {this->a = a;this->b = 0;}Test TestAdd1(Test &t1) {Test t(this->a + t1.a, this->b + t1.b);return t;}void TestAdd2(Test &t1) {this->a = a + t1.a;this->b = b + t1.b;}Test TestAdd3(Test &t1) {this->a = this->a + t1.a;this->b = this->b + t1.b;return *this; //如果想返回一个对象的本身,在成员方法中 使用*this返回}//返回一个引用 相当于返回变量自身Test& TestAdd4(Test &t1) {this->a = this->a + t1.a;this->b = this->b + t1.b;return *this; //相当于把*(&t1)又回到了t1元素}void printT() {cout << "a:" << a << " b:" << b << endl;}~Test() {cout << "析构函数" << endl;}};
//Test TestAdd1(Test &t1)
//void TestAdd2(Test &t1)
//Test TestAdd3(Test &t1)
//Test& TestAdd4(Test &t1)
void test01() {Test t1(10, 20);Test t2(100, 200);Test t3 = t1.TestAdd1(t2);t3.printT();
}
/*
析构函数
a:110 b:220
析构函数
析构函数
析构函数
*/
void test02() {Test t1(10, 20);Test t2(100, 200);t1.TestAdd2(t2);t1.printT();
}
/*
a:110 b:220
析构函数
析构函数
*/
void test03() {Test t1(10, 20);Test t2(100, 200);//((t1 += t2) += t2 )+= t2;//t1.TestAdd2(t2).TestAdd2(t2); 报错 无法连加 t1.TestAdd2(t2)返回值为空t1.TestAdd3(t2).TestAdd3(t2); //a:110 b:220 //t1.TestAdd3(t2)返回为匿名对象//所以在第二次.TestAdd3(t2)时是匿名对象的相加,并不是t1t1.printT();
}
/*
析构函数
析构函数
a:110 b:220
析构函数
析构函数
*/
void test04() {Test t1(10, 20);Test t2(100, 200);//如果相对一个对象连续调用成员方法,每次都会改变对象本身,成员方法需要返回引用t1.TestAdd4(t2).TestAdd4(t2); //a:210 b:420 //t1.TestAdd4(t2)返回的是计算后的对象本身//所以在第二次.TestAdd4(t2)时是计算后的对象相加t1.printT();
}
/*
a:210 b:420
析构函数
析构函数
*/
int main() {cout << "-----------test01-----------" << endl;test01();cout << "-----------test02-----------" << endl;test02();cout << "-----------test03-----------" << endl;test03();cout << "-----------test04-----------" << endl;test04();return 0;
}
#endif