C++学习笔记_002_对象特性(续)

1. 静态成员

在成员变量/函数前加关键字static,称为静态成员(static member)

静态成员分为:

静态成员变量示意:

#include <iostream>
using namespace std;

class person {
public:
	static int m_A;
};

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

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

运行上面的代码可以发现第二次访问p中的m_A成员时值已经被改为了200(所有对象共享静态成员的数据):

 因此,访问静态成员变量有两种方式:

person p;
cout << p.m_A << endl; //通过对象进行访问
cout << person::m_A << endl; //通过类名进行访问

静态成员变量也有访问权限,可以设置private防止类外访问。

静态成员函数示意:

#include <iostream>
using namespace std;

class person {
public:
	int m_B;
	static int m_A;
	static void func() {
		m_A = 100; // 静态成员函数可以访问静态成员变量
		// m_B = 200;  报错,无法区分是哪个对象的m_B
		cout << "static void func 调用" << endl;
	}
};


int person::m_A = 0;
//
//void test01() {
//	person p;
//	cout << p.m_A << endl;
//	person p2;
//	p2.m_A = 200;
//	cout << p.m_A << endl;
//}

void test02() {
	person p;
	p.func(); //通过对象访问
	person::func(); //通过类名访问
}

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

同样,静态成员函数有通过对象/类名两种访问方法,有访问权限。

静态成员函数可以访问静态成员变量,不可以访问非静态成员变量。

2. C++对象模型和this指针

C++编译器为每个空对象分配一个字节空间(8bit):

非静态成员变量,属于类的对象上,记入类空间,静态成员变量,不属于类对象上,不计入空间。

成员变量和成员函数分开存储,成员函数不属于类对象上。

每一个非静态成员函数只会诞生一份函数实例,多个同类型对象会共用一块代码。

this指针(this pointer)指向被调用的成员函数所属对象——用来区分哪个对象调用自己:

this指针隐含在每个非静态成员函数内,无需定义可直接使用。

#include <iostream>
using namespace std;

class person {
public:
	int age;
	person(int age) {
		this->age = age;
	}
	person& addage(person &p) {
		this->age += p.age; //this解决名称冲突
		//this指向p2的指针,*指向p2本体
		return *this; //返回对象本身
	}
};


void test01() {
	person p1(18);
	cout << "age = " << p1.age << endl;
	person p2(10);
	p2.addage(p1).addage(p1).addage(p1); //链式编程思想
	cout << "age = " << p2.age << endl;
}

int main() {
	test01();
	system("pause");
	return 0;
}

使用引用方式&返回,不会新建对象,用this进行重复累加p1_age操作:

this指针的本质是指针常量,this指针的指向不可修改(只能修改指向的值)

3.const修饰成员函数

在成员函数后加const修饰的是this指针指向的值,使之不可修改。

常对象不能修改成员属性,但可以修改静态变量的值,加了mutable的值,常对象也能修改。

#include <iostream>
using namespace std;

class person {
public:	
	static int nation;
};
int person::nation = 0;

void test01() {
	const person p;
	p.nation = 1;
	cout << p.nation << endl;
}

int main() {
	test01();
	system("pause");
	return 0;
}
//输出结果为1

 

4.友元

友元(friend)的目的是让一个函数/类访问另一个类中的私有(private)成员。

 全局函数做友元:

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

class building {
	friend void goodfriend(building* build); // 全局函数做友元
public:
	building() {
		m_livingroom = "live";
		m_bedroom = "bed";
	}
public:
	string m_livingroom;
private:
	string m_bedroom;
};

void goodfriend(building *build) {
	cout << "goodfriend visiting:" << build->m_livingroom << endl;
	cout << "goodfriend visiting:" << build->m_bedroom << endl;
}

int main() {
	building myhome;
	goodfriend(&myhome);
	system("pause");
	return 0;
}

类外的goodfriend函数可以访问类中的private成员m_bedroom。
 

类作为友元:

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

class building {
	// friend void goodfriend(building* build); 全局函数做友元
	friend class goodfriend; //类作为友元
public:
	building() {
		m_livingroom = "客厅";
		m_bedroom = "卧室";
	}
	string m_livingroom;
private:
	string m_bedroom;
};

class goodfriend {
public:
	goodfriend();
    void visit();
	building* build;
};

goodfriend::goodfriend() {
	build = new building;
}

void goodfriend::visit() {
	cout << "goodfriend visiting:" << build->m_livingroom << endl;
	cout << "goodfriend visiting:" << build->m_bedroom << endl;
}

void test01() {
	goodfriend g1;
	g1.visit();
}


//void goodfriend(building *build) {
//	cout << "goodfriend visiting:" << build->m_livingroom << endl;
//	cout << "goodfriend visiting:" << build->m_bedroom << endl;
//}


int main() {
	//goodfriend(&myhome);
	test01();
	system("pause");
	return 0;
}

成员函数作为友元:

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

class building;

class goodfriend {
public:
	goodfriend();
	void visit1();
	void visit2();
	building* build;
};

class building {
	// friend void goodfriend(building* build); 全局函数做友元
	// friend class goodfriend; 类作为友元
	friend void goodfriend::visit1(); // 成员函数作为友元
public:
	building() {
		m_livingroom = "客厅";
		m_bedroom = "卧室";
	}
	string m_livingroom;
private:
	string m_bedroom;
};



goodfriend::goodfriend() {
	build = new building;
}

void goodfriend::visit1() {
	cout << "goodfriend visiting:" << build->m_livingroom << endl;
	cout << "goodfriend visiting:" << build->m_bedroom << endl;
}

void goodfriend::visit2() {
	cout << "goodfriend visiting:" << build->m_livingroom << endl;
	// cout << "goodfriend visiting:" << build->m_bedroom << endl;
}

void test01() {
	goodfriend g1;
	g1.visit1();
	g1.visit2();
}


//void goodfriend(building *build) {
//	cout << "goodfriend visiting:" << build->m_livingroom << endl;
//	cout << "goodfriend visiting:" << build->m_bedroom << endl;
//}


int main() {
	//goodfriend(&myhome);
	test01();
	system("pause");
	return 0;
}

注意,goodfriend的定义要放在building前,否则building将无法定义其内部成员函数的友元,又因goodfriend内有创建building类的指针,所以要在其定义前声明building,最后,友元的设定需放在类定义的最开始。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值