【C++】C++对象初探及友元

C++对象初探及友元


文章目录


前言

本篇文章将讲到C++对象初探,this指针的使用,空指针访问成员函数,常函数和常对象,全局函数做友元函数,类作为友元类,成员函数作为友元函数。


一、C++对象初探

类中的成员变量 和 成员函数 是分开存储的

只有非静态成员变量 属于类对象上

空类的sizeof结果 1

cpp 复制代码
#define  _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;

class Person
{
public:
	int m_A;  //只有非静态成员变量  属于类对象上
	void fun()  //成员函数  并不属于类对象上
	{

	}
	static int m_B; //静态成员变量  不属于类对象上

	static void func2()//静态成员函数  不属于类对象上
	{

	}

	double m_C;
};

void test01()
{
	//空类的sizeof结果是1  原因  每个对象都应该在内存上有独一无二的地址,因此给空对象分配1个字节空间
	Person p1;
	//  空对象 大小 1
	cout << "sizeof = " << sizeof(p1) << endl;
}

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

二、this指针的使用

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

this指针可以解决名称冲突

this指针 隐式加在每个成员函数中

*this 就是本体

p1.personAddPerson(p2).personAddPerson(p2).personAddPerson(p2); //链式编程

cpp 复制代码
#define  _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;

class Person
{
public:
	Person(int age)
	{
		//用途1 :解决名称冲突
		this->age = age;
	}
	//this指针 隐式加在每个成员函数中
	bool compareAge(Person& p)
	{
		if (this->age == p.age)
		{
			return true;
		}
		return false;
	}

	Person& personAddPerson(Person& p)
	{
		this->age += p.age;
		return *this;  //*this 就是本体
	}
	
	int age;
};

void test01()
{
	//this指针 指向 被调用的成员函数 所属的对象
	Person p1(10);
	cout << "p1的年龄为:" << p1.age << endl;

	Person p2(10);

	bool ret = p1.compareAge(p2);
	if (ret)
	{
		cout << " p1与p2年龄相等 " << endl;
	}

	p1.personAddPerson(p2).personAddPerson(p2).personAddPerson(p2);  //链式编程
	cout << "p1的年龄为: " << p1.age << endl;
}


int main() {

	test01();

	system("pause");
	return EXIT_SUCCESS;
}

三、空指针访问成员函数

如果成员函数中没有用到this指针,可以用空指针调用成员函数

如果成员函数中用到了this,那么这个this需要加判断,防止代码down掉

cpp 复制代码
#define  _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;

class Person
{
public:
	void showClass()
	{
		cout << "class Name is Person" << endl;
	}

	void showAge()
	{
		if (this == NULL)
		{
			return;
		}
		m_Age = 0;
		cout << "age = " << this->m_Age << endl;
	}
	int m_Age;
};


void test01()
{
	Person* p = NULL;

	//p->showClass();

	p->showAge();

}

int main() {
	test01();


	system("pause");
	return EXIT_SUCCESS;
}

四、常函数和常对象

常函数

成员函数 声明后面加const

void showPerson() const

const目的是为了修饰成员函数中的this指针,让指针指向的值不可以修改

有些属性比较特殊,依然在常函数或者常对象中可以修改,需要加入关键字 mutable
常对象

const Person p

常对象也不许修改成员属性

常对象只能调用常函数

对于成员函数 ,可不可以 用static 和 const同时修饰 ,不可以

cpp 复制代码
#define  _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;

class Person
{
public:
	Person(int age)
	{
		this->m_Age = age;
	}

	//常函数 : 修饰成员函数中的 this指针,让指针指向的值不可以修改
	void showPerson() const
	{
		//m_Age = 100;
		
		m_A = 100;
		//this指针的本质: const Person * const this 
		//this = NULL; //指针的指向不可以修改,而指针指向的值 可以改
		cout << "person age = " << this->m_Age << endl;
	}
	void func()
	{
		m_Age = 100;
		cout << "func调用" << endl;
	}

	int m_Age;
	mutable int m_A; //常函数中或常对象 有些特殊属性依然想修改,加入关键字 mutable
};


void test01()
{
	//常对象
	const Person p1(10);
	//p1.m_Age = 10;
	p1.m_A = 10;

	p1.showPerson();

	//p1.func(); //常对象 只能调用常函数
}

int main() {

	test01();

	system("pause");
	return EXIT_SUCCESS;
}

五、全局函数做友元函数

利用friend关键字让全局函数 goodGay作为本类好朋友,可以访问私有成员

friend void goodGay(Building * buliding);

cpp 复制代码
#define  _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
#include <string>

class Building
{
	friend void goodGay(Building& building);
public:
	Building()
	{
		this->m_SittingRoom = "客厅";
		this->m_BedRoom = "卧室";
	}
public:
	string m_SittingRoom;
private:
	string m_BedRoom;
};


//好基友全局函数  可以访问Building的私有属性
void goodGay(Building& buliding)
{
	cout << "好基友正在访问:" << buliding.m_SittingRoom << endl;

	cout << "好基友正在访问:" << buliding.m_BedRoom << endl;
}


void test01()
{
	Building buliding;
	goodGay(buliding);
}

int main() {
	test01();


	system("pause");
	return EXIT_SUCCESS;
}

六、类作为友元类

让goodGay类作为 Building的好朋友,可以访问私有成员

friend class GoodGay;

cpp 复制代码
#define  _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
#include <string>
class Building;
class GoodGay
{
public:
	GoodGay();

	void visit();

	Building* m_building;
};

class Building
{
	//让goodGay类作为 Building的好朋友,可以访问私有成员
	friend class GoodGay;

public:
	Building();

	string m_SittingRoom;

private:
	string m_BedRoom;
};

Building::Building()
{
	this->m_SittingRoom = "客厅";
	this->m_BedRoom = "卧室";
}

GoodGay::GoodGay()
{
	this->m_building = new Building;
}
void GoodGay::visit()
{
	cout << "好基友正在访问: " << this->m_building->m_SittingRoom << endl;
	cout << "好基友正在访问: " << this->m_building->m_BedRoom << endl;
}


void test01()
{
	GoodGay gg;
	gg.visit();
}

int main() {

	test01();

	system("pause");
	return EXIT_SUCCESS;
}

七、成员函数作为友元函数

让GoodGay类中的 visit成员函数作为友元

friend void GoodGay::visit();

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
#include <string>
class Building;
class GoodGay
{
public:

	GoodGay();

	void visit(); //可以访问building的私有

	void visit2(); // 不可以访问building的私有

	Building* m_building;
};

class Building
{
	//让GoodGay类中的 visit成员函数作为友元
	friend void GoodGay::visit();
public:
	Building();

	string m_SittingRoom;

private:
	string m_BedRoom;
};

Building::Building()
{
	this->m_SittingRoom = "客厅";
	this->m_BedRoom = "卧室";
}

GoodGay::GoodGay()
{
	this->m_building = new Building;
}

void GoodGay::visit()
{
	cout << "好基友正在访问: " << this->m_building->m_SittingRoom << endl;
	cout << "好基友正在访问: " << this->m_building->m_BedRoom << endl;
}

void GoodGay::visit2()
{
	cout << "好基友正在访问: " << this->m_building->m_SittingRoom << endl;
	//cout << "好基友正在访问: " << this->m_building->m_BedRoom << endl;
}


void test01()
{
	GoodGay gg;
	gg.visit();
	gg.visit2();
}

int main() {

	test01();

	system("pause");
	return EXIT_SUCCESS;
}

总结

到这里这篇文章的内容就结束了,谢谢大家的观看,如果有好的建议可以留言喔,谢谢大家啦!

相关推荐
yayaya1521 分钟前
javaScriptBOM
开发语言·javascript·ecmascript
项目申报小狂人2 分钟前
广义正态分布优化算法(GNDO)Generalized Normal Distribution Optimization
算法·概率论
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭8 分钟前
C#都可以找哪些工作?
开发语言·c#
陵易居士10 分钟前
力扣周赛T2-执行操作后不同元素的最大数量
数据结构·算法·leetcode
爱打APEX的小李13 分钟前
拷贝构造和赋值运算符重载
c++
霁月风22 分钟前
设计模式——工厂方法模式
c++·设计模式·工厂方法模式
夜阳朔29 分钟前
《C++ Primer》第三章知识点
c++·编程语言
凡人的AI工具箱30 分钟前
每天40分玩转Django:Django管理界面
开发语言·数据库·后端·python·django
每天写点bug44 分钟前
【go每日一题】:并发任务调度器
开发语言·后端·golang
一个不秃头的 程序员1 小时前
代码加入SFTP Go ---(小白篇5)
开发语言·后端·golang