C++学习笔记:类对象作为类成员、静态成员以及this指针

 类对象作为类成员

汽车由各种零件,如轮胎,如发动机,其中这些零件又可以归属到零件类

所以我们可以说汽车类中包含了一个零件类

那么,问题来了:汽车类里包含了零件类,那么既然是类,就有构造函数和析构函数呀,谁的函数先实现呢?

我们先给出答案,后边代码验证

构造顺序:因此当其他类对象作为本类成员,构造时先构造类对象,再构造自身。

析构顺序:与构造相反

#include<iostream>
#include<string>
using namespace std;


//手机类
class Phone {
public:
	Phone() {

	}

	Phone(string pName):m_Pname(pName) {
		cout << "Phone的构造函数调用" << endl;
	}
	
	~Phone() {
		cout << "Phone的析构函数的调用" << endl;

	}

	//手机名
	string m_Pname;
};

class Person {
public:

	Person(string name, string pName):m_Name(name),m_Phone(pName) {
		cout << "Person的构造函数调用" << endl;
	}
	
	~Person() {
		cout << "Person的析构函数的调用" << endl;
	}
	//姓名
	string m_Name;

	//手机
    
	Phone m_Phone;
};



void test01() {
	Person p("张三", "iphone");
	cout << p.m_Name << "拿着: " << p.m_Phone.m_Pname << endl;
}

int main() {

	test01();

	return 0;

}

注意!!!在Person里,当我们底下创建Person p时候,传入的参数pName是string类型,而我们声明的pName是Phone类型的,Phone 是一个对象。若理解为值赋给m_Phone的话,就错误了,因为值的话,m_Phone是Phone类型。所以应该这样理解,此处就依赖我们讲过的隐式转换法,相当于 Phone m_Phone = pName,用了隐式转换法,而上边刚好有一个有参构造函数。 

静态成员

定义:静态成员就是在成员变量和成员函数前加上关键字static,称为静态成员

静态成员变量不属于某个对象,因为所有对象都共享同一份数据如Person p,p1共享一个属性m_A。

分类:

分为两类:

静态成员变量

特点:

  1. 所有对象共享同一份数据
  2. 在编译阶段分配内存
  3. 类内声明,类外初始化

静态成员变量有两种访问方式:
           1.通过对象进行访问
            2.通过类名访问,如要喝一杯瑞幸,可以直接去附近分店做一杯,也可找到他总部做一杯
            如:cout << Person::m_A << endl
            静态成员变量也有访问权限 

#include<iostream>
using namespace std;

class Person {
public:
	static int m_A;    //类内声明
private:
	static int m_B;
};

int Person::m_B = 200;
int Person::m_A = 100;//类外初始化


void test01() {
	Person p;
	cout << p.m_A << endl;
	Person p2;
	p2.m_A = 200;
	cout << p.m_A << endl;  //此时共享数据已经被更改了
	//cout << Person::m_B;  //error,私有成员类外无法访问

}

int main() {
	test01();
	return 0;
}

静态成员函数

访问方式:通过对象访问、通过类名访问

特点 

  1. 所有对象共享同一个函数
  2. 静态成员函数只能访问静态成员变量:因为如果可以访问普通成员变量的话,无法区分是更改哪个对象的成员变量,因为静态成员变量是所有对象共有的,不需要区分,而普通成员变量的话需要区分
    #include<iostream>
    using namespace std;
    
    //静态成员函数:
    //所有成员共享同一个函数
    //静态成员函数只能访问静态成员
    
    //通过对象访问
    //通过类名访问
    
    class Person {
    public:
    	
    	static void func() {
    		m_A = 100;
    		//m_B = 200;  //error,m_B为非静态成员,当使用Person::去调用函数时,编译器不知道应该修改哪个对象的m_B;
    		//而m_A所有成员都公用,调用去修改时一改全改
    		//理解不了这种的话,就理解为静态成员编译前就初始化,然后就分配内存
    		cout << "static void func调用" << endl;
    	}
    	int m_B;
    	static int m_A;
    private:
    	static void func2() {
    		cout << "static void func2调用" << endl;
    	}
    };
    
    int Person::m_A = 0;
    
    void test01() {
    	Person p;
    	p.func();
    	Person::func();
    	//Person::func2(); //error,类外无法访问私有静态成员函数
    }
    
    int main() {
    	test01();
    	return 0;
    }

this指针

 在C++中,成员变量和成员函数是分开存储的,每一个非静态成员函数只会由一个实例,

每一个非静态成员函数只会诞生一份函数实例,所以会出现多个同类型对象共同使用这个函数,也就是共用一份代码,那么这一块代码如何区分哪个对象调用了它自己呢?

答案是用this指针。

this指针指向被调用的成员函数所属的对象 


静态函数没this,因为他不需要指向,他不属于任何一个对象
this隐含在每一个非静态成员函数中,属于一种指针。

使用时机:

  1. 返回对象本身用*this
  2. 当形参和成员变量同名时,可用this指针来区分 

使用方法:

  1. 1.在类的非静态成员函数中返回对象本身可使用 return *this;
  2. 当形参和成员变量同名时,可用this指针来区分(解决名称冲突)
  3. this指针本质,指针常量, 类似 Person* sonst this
#include<iostream>
using namespace std;

class Person {
public:

//解决名称冲突
	Person(int age) {
		//age = age;                     //error,目的是赋值,但是出现错误;
		                                 //可能所有age都被当成参数age了
		this->age = age;
	}


    /*void PersonAdd(Person& p) {
		this->age += p.age;        
	}*/

	Person PersonAdd(Person& p) {
		this->age += p.age;
		return *this;                   //this为指向p2的一个指针,*解引用
	}

	int age;
};

void test01() {
	Person p1(19);
	cout << "p1的年龄为:" << p1.age << endl;
}


void test02() {
	Person p1(10);
	Person p2(20);

	//2.若是函数返回没有&引用的话,此时第一次函数返回一个复制体p2·,然后再调用再生成一个复制体p2··,再一次p2···
	//3.而我们最后输出的是p2
	//4.有了引用的话,返回的是p2的别名
	
	//5.这里这个p2···被p3接受
	Person p3(10);
	p3 = p2.PersonAdd(p1).PersonAdd(p1).PersonAdd(p1);

    //1.此时想这样加好几次,但p2返回值为void,如果返回值为Person类型就可以调用这个函数
	p2.PersonAdd(p1).PersonAdd(p1).PersonAdd(p1);  
	                                 
	cout << p2.age << endl;
}

int main() {
	test01();
	test02();
	return 0;
}

此处p2.PersonAdd(p1) .PersonAdd(p1) .PersonAdd(p1) ;为链式编程思想,仔细想想我们还在哪见过这种方法

在cin输出一个值时候我们是不是习惯在后边加一个endl,此时 cin << a << endl;就是一个链式编程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值