类的特殊成员

类的静态成员

1.静态数据成员(static)

  • 类的静态数据成员是由该类的所有对象共同维护和使用
  • 类的声明是抽象的,因此类中只能声明静态数据成员,即静态数据成员的初始化需要在类的外部进行
  • 类的声明是抽象的,可以通过类名直接访问静态数据成员,用法为“类名::标识符”
    例:统计学生数目
class student
{
	public:
		student(const char *s);
		~student();
	private:
		static int count;  //无法直接初始化
		string name;
};
int student::count=0;

Student::Student(const char *s)
{ 
	name=s;
	count++;
}

Student::~Student()
{
	count--;
	cout<<name<<" is dead "<<count<<endl;
}

int main(int argc, char** argv) 
{
	Student a("zhangsan");
	Student b("lisi");
	Student c("wangwu");
} 
		

在这里插入图片描述
2.静态成员函数(static)

  • 类的静态成员函数是由该类的所有对象共同维护和使用
    上面代码Student类加一个静态成员函数
	static void print()
		{
			cout<<count<<endl;
		}

主函数添加

a.print();

在这里插入图片描述

类的组合

一个类内嵌其他类的对象作为数据成员的情况。
创建组合类的对象时,各个内嵌对象也将被自动创建。

内嵌类的构造函数:
类名::类名(形参表):内嵌对象1(形参表),内嵌对象2(形参表)…
{
}

构造函数调用顺序:按照组合类中声明顺序先执行内嵌对象构造函数,再执行自身构造函数

#include<bits/stdc++.h>
using namespace std; 

class A1
{
	public:
		A1(int x,int y);
		~A1();
	private:
		int value1;
		int value2;
};

A1::A1(int x,int y)
{
	value1=x;
	value2=x;
	cout<<"A1 is finished\n"; 
} 
A1::~A1()
{
	cout<<"A1  is dead\n";
} 


class A4
{
	public:
		A4(int x,int y);
		~A4();
	private:
		int value1;
		int value2;
};

A4::A4(int x,int y)
{
	value1=x;
	value2=x;
	cout<<"A4 is finished\n";
} 
A4::~A4()
{
	cout<<"A4 is dead\n";
} 

class A
{
	public:
		A(int x,int y);
		~A();
	private:
		A1 a;  //a先声明
		A4 b; //b后声明
};

A::A(int x,int y):a(x,y),b(y,x)
{
	cout<<"A is finished\n";	
}

A::~A()
{
	cout<<"A is dead\n";
}

int main(int argc, char** argv) 
{
	A c(1,2); 
} 


在这里插入图片描述
内嵌对象声明顺序为a,b
构造函数执行顺序为a,b,A
析构函数执行顺序为A,b,a(其中内嵌对象所在类A1,A4析构函数必须手动声明)

友元(friend)

可以访问类的私有成员和保护成员的外部成员

关键字friend可以将(一般函数,其他类的成员函数,其他类)声明为本类的友元,这样友元可以访问本类的隐藏信息(private和protected)

1.友元函数

友元函数的特点是能够访问类中的私有成员的非成员函数。友元函数从语法上看,他和普通函数相同,即在定义上和调用上和普通函数相同。下面举一例子说明友元函数的应用。

class Point
{
	public:
		Point(double xx, double yy) 
		{ 
			x=xx; y=yy; 
		}
		void Getxy();
		friend double Distance(Point &a, Point &b);  //该函数是友元函数的声明
		private:
		double x,y;
};

{
	double dx = a.x - b.x;
	double dy = a.y - b.y;
	return sqrt(dx*dx+dy*dy);
}
		
void Point::Getxy()
{
	cout<<"("<<x<<","<<y<<")"<<endl;
}
int main()
{
	Point p1(3.0,4.0);
	Point p2(6.0,8.0);
	p1.Getxy();
	p2.Getxy();
	double d = Distance(p1, p2);
	cout<<"Distance is "<<d<<endl;
}

在这里插入图片描述
2.友元类
友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。
当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一类的友元类。定义友元类的语句格式如下:
friend class 类名;
其中:friend和class是关键字,类名必须是程序中的一个已定义过的类。

  例如,以下语句说明类B是类A的友元类:
  class A
  {
         …
  public:
         friend class B;
         …
  };
  经过以上说明后,类B的所有成员函数都是类A的友元函数,能存取类A的私有成员和保护成员。 
#include <iostream>
using namespace std;
class A
{
public:
    friend class C;                         //这是友元类的声明
private:
    int data;
};

class C             //友元类定义,为了访问类A中的成员
{
public:
    void set_show(int x, A &a) { a.data = x; cout<<a.data<<endl;}
};

int main(void)
{
    class A a;
    class C c;
    c.set_show(1, a);
    return 0;
}

3、友元成员函数
使类B中的成员函数成为类A的友元函数,这样类B的该成员函数就可以访问类A的所有成员了。
当用到友元成员函数时,需注意友元声明和友元定义之间的相互依赖,在该例子中,类B必须先定义,否则类A就不能将一个B的函数指定为友元。然而,只有在定义了类A之后,才能定义类B的该成员函数。更一般的讲,必须先定义包含成员函数的类,才能将成员函数设为友元。另一方面,不必预先声明类和非成员函数来将它们设为友元。

#include <iostream>
using namespace std;
class A;    //当用到友元成员函数时,需注意友元声明与友元定义之间的互相依赖。这是类A的声明
class B
{
public:
    void set_show(int x, A &a);             //该函数是类A的友元函数
};

class A
{
public:
    friend void B::set_show(int x, A &a);   //该函数是友元成员函数的声明
private:
    int data;
    void show() { cout << data << endl; }
};

void B::set_show(int x, A &a)       //只有在定义类A后才能定义该函数,毕竟,它被设为友元是为了访问类A的成员
{
    a.data = x;
    cout << a.data << endl;
}

int main(void)
{
    class A a;
    class B b;
    b.set_show(1, a);
    return 0;
}

(1) 友元关系不能被继承。
(2) 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
(3) 友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值