C++-静态成员与友元

静态成员

C语言中可以通过全局变量实现数据共享,在程序的任何位置都可以访问

C++中希望某个类的多个对象之间实现数据共享,可以通过static建立一个被局限在类中使用的全局资源,该类型资源被称为静态变量(可以理解为局部变量在类中使用的全局变量)

静态成员变量

被static修饰的成员变量即为静态成员变量

class 类名{
    static 数据类型 变量名;//声明
};

数据类型 类名::变量名 = 初值;//定义和初始化。
#include <iostream>
using namespace std;

class A{
public:
	int m_date;
	static int s_date ;

	A(int date):m_date(m_date) {};
};

int A:: s_date = 200;//定义并初始化

int main(int argc, const char *argv[])
{
	cout << A:: s_date << endl;
	A s1(12);

	cout << "s1 size:" << sizeof(s1) << endl;
	
	cout << s1.s_date << endl;
	A s2 = 100;
	cout << s2.s_date << endl;
	return 0;
}

实例化对象时只实现非静态成员变量

访问方式:

  • 类名::静态成员变量;
  • 对象.静态成员变量;

静态成员函数

被static修饰的成员函数即为静态成员函数;

class 类名{
访问控制限定符:
    static 返回类型 函数名(形参表){...}
};

注意:

  • 静态成员函数可以直接定义在类的内部,也可以定义在类的外部,这一点和普通成员函数没有区别。
  • 静态成员函数没有this指针,没有const属性,可以把静态函数理解为被限制在类中使用的全局函数。
  • 静态成员函数中只能访问静态成员,但是在非静态成员函数中既可以访问静态成员也可以访问非静态成员。
  • 静态成员函数和静态成员变量一样,也要收到类的访问控制权限的约束。

在类的外部访问静态成员函数

类名::静态成员函数(实参表);

对象.静态成员函数(实参表);

#include <iostream>
using namespace std;

class A{
	
public:
	int s_date;
	static int m_date;

	A(int date = 0):s_date(date) {}

	void func1(void) {
		cout << "非静态成员函数:" << s_date << endl;
		cout << m_date << endl;
	}

	static void func2(void) {
		//cout << "静态成员函数:" << s_date << endl;//不能访问非静态变量
		cout << "静态成员变量" << endl;
		cout << m_date << endl;
	}
};

int A::m_date = 100;
int main(int argc, const char *argv[])
{
	A s1(200);
	s1.func1();

	s1.func2();

	//A::func1();//errno
	A::func2();
	
	return 0;
}

友元

类的封装具有信息隐藏能力,但也带来了访问效率的问题。C++通过友元给某些函数一项特权,可以访问类中的私有成员,使用的关键字是friend。

友元函数

友元函数可以直接访问类的私有成员

class X{
    friend T f(...);//声明f为x的友元
    ...
};

T f(...) {}//友元不是类的成员函数。
#include <iostream>
#include <cmath>
using namespace std;

class point{
private:
	int x, y;

public:
	point(int a = 0, int b = 0) {
		x = a, y = b;
	}

	int getx(){
		return x;
	}

	int gety() {
		return y;
	}

	friend int dist2(point&, point&);
};

int dist(point& p1, point& p2) {
	double X = p1.getx() - p2.getx();
	double Y = p1.gety() - p2.gety();

	return sqrt(X*X + Y*Y);

}


int dist2(point& p1, point&p2) {
	double X = p1.x - p2.x;
	double Y = p1.y - p2.y;

	return sqrt(X*X + Y*Y);

}
int main(int argc, const char *argv[])
{
	point p1(6, 8), p2(4, 3);
	cout << dist(p1, p2) << endl;
	cout << dist2(p1, p2) << endl;
	
	return 0;
}

友元类

一个类可以是另一个类的友元,友元类的所有成员函数都是另一个类的友元函数,能够直接访问另一个类的所有成员。

友元类不是双向的,B是A的友元类,A不一定是B的友元类。

#include <iostream>
using namespace std;

class A{
private:
	int x, y;

public:
	A(int a = 0, int b = 0) {
		x = a, y = b;
	}

	friend class B;

};

class B{
private:
	int z;

public:
	B(int i = 0) {
		z = i;
	}
	int add(const A& a) {
		return a.x + a.y + z;
	}

	int sub(const A& a) {
		return a.x - a.y - z;
	}
};
int main(int argc, const char *argv[])
{
	A s1(3,4);
	B s2(5);

	cout << s2.add(s1) << endl;
	cout << s2.sub(s1) << endl;
	
	return 0;
}

友元成员函数

对一个类,可以指定它的某个成员函数是另一个类的友元,也就是友元成员函数。

#include <iostream>
using namespace std;

class A;

class B{
private:
	int z;

public:
	B(int i = 0) {
		z = i;
	}

	int add(const A&);
	//int sub(const B&);
};

class A{
private:
	int x, y;

public:
	A(int a = 0, int b = 0) {
		x = a, y = b;
	}

	//friend class B;
	friend int B::add(const A&);//友元函数声明

};
int B::add(const A& a) {
	return a.x + a.y + z;
}

/*int B::sub(const A& a) {
	return a.x - a.y - z;
}*/

int main(int argc, const char *argv[])
{
	A s1(3,4);
	B s2(5);

	cout << s2.add(s1) << endl;
//	cout << s2.sub(s1) << endl;
	
	return 0;
}

单例模式

单例模式(也称单件模式),使用最广泛的设计模式之一。其意图是保证一个类仅有一个实例,并提供一个它的全局访问点,该实例被所有程序模块共享。

面向对象编程中,每个对象都应该抽象代表一个设备,并通过对象完成对某个具体设备的管理和维护。

对于有些类只能有一个实例很重要,例如打印机管理器,设备管理器,任务管理器等。

实现单例模式的三个主要步骤:

  • 私有化构造函数
class singleton{
private:
    singleton(void) {...}
    singleton(const signleton &that) {}
    ...

};
  • 使用静态成员变量维护唯一的单例对象
#include <iostream>
using namespace std;

class sprt{
private:
	int m,i;
	sprt(int i = 0) {
		this->i = i;
	}                        //私有构造函数
	sprt(const sprt& that) {

	}

	static sprt m_sprt;
public:

	static sprt& getsprt(void) {
		return m_sprt;
	}
	void print(void) {
		cout << i << endl;
	}
};

sprt sprt:: m_sprt = 100;

int main(int argc, const char *argv[])
{
	//sprt s4 = 200; errno
	sprt& s1 = sprt::getsprt();
	sprt& s2 = sprt::getsprt();
	sprt& s3 = sprt::getsprt();

	cout << &s1 << endl;
	cout << &s2 << endl;
	cout << &s3 << endl;

	s1.print();

	
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值