一、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); //匿名对象直接转化为t3
t3.printT();
Test t4;
t4 = t1.TestAdd1(t2); //匿名对象复制给t4
t4.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)时是匿名对象的相加,并不是t1
t1.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