C++ this原理与友元函数友元类

本文介绍了C++中的可变参数技术,通过`va_list`、`va_start`、`va_arg`和`va_end`进行参数的动态处理。探讨了静态成员的声明、初始化和使用规则,强调了静态成员函数只能操作静态成员。此外,解释了`this`指针在对象中的作用,用于访问当前对象的成员。还讨论了`const`修饰的`this`的意义,即在成员函数中禁止修改对象状态。最后,介绍了友元函数的概念,展示了如何通过友元函数访问类的私有成员,并对比了静态函数、友元函数、普通函数、构造函数、析构函数、拷贝构造函数之间的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

可变参数

#include <iostream>
#includ <stdarg.h>//可变参数支持

//对比java的设计确实有点脑残
void sum(int count,...){
	va_list vp; // 可变参数的动作
	// 参数一: 可变参数开始的动作vp
	// 参数二:内部需要一个 存储地址用的参考值,如果没有,内部就无法处理存放参数
	//count的用处,当循环遍历的时候作为可变参数的长度
	va_start(vp,count);
	//到这里后:vp就有丰富的信息
	// 取出可变参数的一个值
	int number = va_arg(vp, int);
	cout << number << endl;
	
	// 取出可变参数的一个值
	int number = va_arg(vp, int);
	cout << number << endl;
	
	// 取出可变参数的一个值,取不到后会取出系统值,乱码
	int number = va_arg(vp, int);
	cout << number << endl;
	//关闭阶段
	va_end(vp);
}

int main(){
	sum(3,6,7,8);
	return 0;
}

static关键字

class Dog{
	public:
		char * info;
		int age;
		//编译不成功,不允许这样初始化
		//static int id = 9;
		static int id;
		Dog (){
			//运行报错
			//id = 9;
		}

		static void update(){
			//运行报错
			//id = 9;
		}
};


int main(){
	Dog dog;
	dog::update();//类名::可以调用静态函数
	
	returnt 0;
}

/**
*1、直接使用类名::静态成员(字段/函数)
*2、静态的属性必须初始化,然后再实现
*3、静态的函数只能操作静态的属性和方法
*/


class Dog{
	public:
		char * info;
		int age;
		//编译不成功,不允许这样初始化
		//static int id = 9;
		
		//先声明
		static int id;
		Dog (){
			//运行报错
			//id = 9;
		}

		static void update(){
			//没有实现的话运行报错,有实现的话可以调用
			id += 100;
			//update2();//静态函数不能调用非静态函数
		}
		void update2(){
			id = 13;
		}
};

// 再实现
int Dog::id = 9;
int main(){
	Dog dog;
	dog.update();//普通函数
	cout << Dog::id << endl;//输出13
	Dog::update();静态函数
	//也可以  dog.update();
	cout << Dog::id << endl;//输出113
	//主要的规则就是先定义,再实现
	returnt 0;
}

C++对象中,为什么需要this

#include <iostream>
using namespace std;

class Student{
private:
	char * name;
	int age;
public:
	static int id;//先声明
public:
	void setName(char * name){
		this->name = name;		
	}
	void setAge(int age){
		this->age = age;
	}
	char * getName(){
		return this->name;
	}
	int getAget(){
		return this->age;
	}
public:
	//默认的无参数构造函数 栈区开辟空间 暴露地址==this指针 跟java一致的思路
};
//再实现
int Student::id = 9527;

int main(){
	Sudent student;
	student.setAge(99);
	student.setName("abce");
	cout << student.getName() << "," << student.getAge() << endl;
	// ==============this
	Sudent student1;
	student1.setAge(88);//设置值的时候它怎么知道是给student1设置值的?
	cout << "student1.getAge:" << student1.getAge() << endl;
	
	//底层我们大概可以分为四个区域:栈区、堆区、全局区域(静态区、常量区、字符串区),代码区域
	//当执行Sudent student1;的时候会执行默认的空参数构造函数,产生的this会指向代码区域的Student
	//代码区域的Student有很多副本,多个Sudent student1;会产生多个this
	
	//静态区域比较好理解,没有this区分,就一份无论修改哪个都是修改同一份
	return 0;
}

const修饰的this意义何在

class Worker{
public:
	char * name;
	int age = NULL;//给默认值0

	//为什么可以修改age
	//默认持有隐式的this(Worker * const this)指针常量
	// 指针的地址不能修改,但是指针指向的值是可以被修改的
	void change(){
		this->age = 78;
	}
	//默认现在:this等价与 const Student * const 常量指针常量
	void changeAction() const {
		//全都不能改
		//只读的
	}
}

友元函数

class Person{
private:
	int age = 0;
public:
	Person(itn age){
		this->age = age;
	}
	int getAge(){
		return this->age;
	}
	//定义友元函数 (声明,没有实现)
	friend void updateAge(Person * person, int age);
};

void change(Person * person, int age){
	//没有提供set,不能修改私有的,那怎么修改呢?
}

//友元函数的实现
void updateAge(Person * person, int age){
	person->age = age;
}
int main(){
	Person p = Person(9);
	updateAge(p,88);//修改成功,跟java对比的话有点脑瘫
	return 0;
}

静态函数,友元函数,普通函数,构造函数,析构函数,拷贝构造函数,有啥区别?
真实开发过程中的规范

//JNI为什么一定要这个东西?(后面到JNI再说)
//头文件.h 定义
#include <iostream>
using namespace std;

#ifndef PIG_H //你有没有这个宏 (java 宏==常量)
#define PIG_H //定义这个宏

class Pig{
private:
	int age;
	char * name;
public:
	//静态成员变量
	static int id;

	//构造函数的声明系统
	Pig();
	Pig(char *); //不写char * 后面的参数,隐藏起来
	Pig(char *,int);//不写int 后面的参数,隐藏起来
	//析构函数
	~Pig();
	//拷贝构造函数
	Pig(const Pig & pig);
	//普通函数 set get
	int getAge();
	char * getNmae();
	void setAge(int);
	void setNmae(char *);
	void showPigInfo() const//常量指针常量 只读
	//静态函数的声明
	static void changeTag(int age);
	//友元函数的声明
	friend void change(Pig * pig,int age);

};
#ENDIF // 关闭/结尾
//实现文件
#include <Pig.h>

//实现构造函数
Pig::pig(){
	cout << "默认构造函数" << endl;
}
Pig::pig(char * name){
	cout << "1个参数构造函数" << endl;
}
Pig::pig(char * name, int age){
	cout << "2个参数构造函数" << endl;
}

//实现析构函数
Pig::~Pig(){
	cout << "析构造函数" << endl;
}
//实现拷贝函数
Pig::Pig(const Pig & pig){
	cout << "拷贝构造函数" << endl;
}

int Pig::getAge(){
	return this->age;
}

int Pig::getAge(){
	return this->age;
}

char * Pig::getName(){
	return this->name;
}

void Pig::setAge(int age){
	this->age = age;
}

void Pig::setName(char * name){
	this->name = name;
}

void Pig::showPigInfo() const {
		//常量指针常量 只读
}

//上面的都是普通,没有特别的,下面的实现就有一点不同
//实现静态属性 不需要增加static关键字
int Pig::id = 878;

//实现静态函数,不需要增加static关键字
void Pig::changeTag(int age) {
}

//友元:不需要关键字friend,也不需要对象::,只需要保证函数名(参数)
void changeAge(Pig * pig,int age){
}

友元类

#include <iostream>
unsing namespace std;

class ImgaeView{
prviate:
	int viewSize;
	friend class Class;// 友元类
};

// java每个类,都会有一个Class,此Class可以操作ImageVew私有变量
class Class{
public:
	ImageView imageView;
	void changeViewSize(int size){
		imageView.viewSize = size;
	}
	int getViewSize(){
		return imageView.viewSize;
	}
};

int main(){
	Class mImageViewClass;
	mImageViewClass.changeViewSize(600);
	cout << mImageViewClass.getViewSize() << endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值