栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++ 9:友元,范围for,静态成员

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++ 9:友元,范围for,静态成员

文章目录
  • 1. 友元
    • 1.1 友元的定义
    • 1.2 友元的分类
    • 1.3 友元的特点
    • 1.4 输入输出流
      • 1.4.1 代码示例1(外部函数友元)
      • 1.4.2 代码示例2(成员函数友元)
      • 1.4.3 代码示例3(类友元)
    • 1.5 外部友元函数
    • 1.6 总结
  • 2. 基于范围的for循环
  • 3. 静态成员
    • 3.1 定义
    • 3.2 c语言静态关键字修饰局部变量
    • 3.3 静态数据成员属性
    • 3.4 mutable关键字和static关键字
    • 3.5 同全局变量相比,使用静态数据成员有两个优势
    • 3.6 静态方法


1. 友元 1.1 友元的定义
  • 友元 friend机制允许一个类授权其他的函数访问类产生 对象 的非公有成员。

  • 友元声明以关键字friend开头,它只能出现在类的声明中,它们不受其在类体中的public,private和protected区的影响。

1.2 友元的分类
  • 外部函数友元
  • 成员函数友元
  • 类友元(模板类的友元函数)
1.3 友元的特点
  1. 不具有对称性、:A是B的友元,并不意味着B是A的友元。

  2. 不具有传递性︰A是B的友元,B是C的友元,但A不是C的友元。

  3. 不具有继承性: Base类型继承Object类型,如果Object类型是A的友元,但Base类型不是A友元。

1.4 输入输出流
  • istream-输入流(标准输入设备cin);
  • ostream-输出流(标准输出设备cout);
  • (错误输出cerr);
  • ifstream-文件输入流;
  • ofstream-文件输出流.
1.4.1 代码示例1(外部函数友元)
#include
using namespace std;
class Int
{
private:
	int value;
public:
	int& Value()
	{
		return value;
	}
	const int& Value() const
	{
		return value;
	}
public:
	Int(int x = 0) :value(x) {}
	//将输出流函数变为Int类型的友元函数,所以输出流函数可以访问Int类型的私有成员
	ostream& operator<<(ostream& out) const
	{
		out << value;
		return out;
	}
	istream& operator>>(istream& in)//注意:不能加const,加const就不能改变了
	{
		in >> value;
		return in;
	}
	friend ostream& operator<<(ostream& out, const Int& it);
};
//重载输出流对象
ostream& operator<<(ostream& out, const Int& it)
{
	out << it.value;
	return out;
}
//重载输入流对象
istream& operator>>(istream& in, Int& it)
{
	it >> in;
	return in;
}
int main()
{ 
	Int a, b;
	a.Value() = 100;
	cout << a << " " << b << endl;
	return 0;
}

运行结果

1.4.2 代码示例2(成员函数友元)
#include
using namespace std;
class Int;
class Base
{
public:
	void func(const Int& it);
};

class Int
{
private:
	int value;
public:
	int& Value()
	{
		return value;
	}
	const int& Value() const
	{
		return value;
	}
public:
	Int(int x = 0) :value(x) {}

	friend void Base::func(const Int& it);
};
void Base::func(const Int& it)
{
	cout << it.value << endl;
}
int main()
{
	Int a(10);
	Base base;
	base.func(a);

	return 0;
}

运行结果

1.4.3 代码示例3(类友元)
#include
using namespace std;

class Int
{
private:
	int value;
public:
	int& Value()
	{
		return value;
	}
	const int& Value() const
	{
		return value;
	}
public:
	Int(int x = 0) :value(x) {}

	friend class Base;//类友元:Base变为了Int的友元,Base可以访问Int所产生对象的所有成员
};
class Base
{
public:
	void func(const Int& it);
	void show(const Int& it);
};
int main()
{
	Int a(10);
	Base base;
	base.func(a);
	base.show(a);

	return 0;
}
1.5 外部友元函数

外部函数友元,友元函数是一个外部函数,没有this指针,不能用const修饰。外部函数作为友元函数时,无this指针。

class Object
{
private:
    int value;
public:
    Object(int x) :value(x) {}
    friend ostream& operator<<(ostream& out, const Object& obj);
};
ostream& operator<<(ostream& out, const Object& obj)
{
    out << obj.value;//外部对象友元:外部函数无法访问对象私有属性
    return out;
}
int main()
{
    Object obj(10);
    cout << obj << endl;
    return 0;
}
1.6 总结
  1. 友元函数不是类的成员函数,在函数体中访问对象的成员,必须用对象名加运算符"."加对象成员名。但友元函数可以访问类产生对象的所有成员,一般函数只能访问类中的公有成员。

  2. 友元函数不受类中的访问权限关键字限制,可以把它放在类的公有、私有、保护部分,但结果一样。

  3. 某类的友元函数的作用域并非该类作用域。如果该友元函数是另一类的成员函数,则其作用域为另一类的作用域,否则与一般函数相同。

2. 基于范围的for循环

for循环新用法

#define _CRT_SECURE_NO_WARNINGS
#include"stdio.h"
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int main()
{
    int ar[] = { 12, 23, 34, 45, 56, 67, 78, 89 };//如果容器不是内置类型,自动识别每个类型

    for (auto& x : ar)//将ar里面的值拷贝到x里,如果为对象,则为引用
    {
        cout << x << endl;
    }
}
3. 静态成员 3.1 定义

static可以修饰类的数据成员,也可以修饰类的函数成员。

由关键字static修饰类体中成员,成为类静态成员(static class member)。类的静态成员为其所有对象共享,不管有多少对象,静态成员只有一份存于公用内存中。静态数据成员被当作该类类型的全局对象。

3.2 c语言静态关键字修饰局部变量
  • 静态关键字修饰局部变量,生存期变为.data
  • 当函数调动时,支队静态变量初始化一次
  • 静态局部变量可以采取引用返回
int fun()
{
    static int x = 0;//1.静态关键字修饰局部变量,生存期变为.data 2.当函数调动时,支队静态变量初始化一次 3.静态局部变量可以采取引用返回
    int y = 10;
    return x;
}
3.3 静态数据成员属性

[1] 设计静态数据成员的目的是信息共享和信息交流

[2] 静态成员在类中声明,在类外进行定义,定义时不添加static关键字,不能在构造函数的初始列表中创建

[3] 在类外访问是共有的,在类的成员函数中静态成员没有this指针


[4] 静态数据是该类所有对象所共有的,可提供同一类型的所有对象之间,信息共享或信息交换的一种方式。

[5] 静态属性的类型是int,short,char,并且是const,可以在类中直接初始化

#include
using namespace std;

class Array
{
private:
	static const unsigned int n = 10;
	static const int ar[n];
};
const int Array::ar[n] = { 1,2,3,4 };

int main()
{
	Array a;
	return 0;
}

[6] 静态数据成员的类型可以是其所属类而非static数据成员只能被声明为该类的指针


3.4 mutable关键字和static关键字
class Object//编译错误,产生无穷递归
{
public:
    int value;
    Object obj;
};
class Object//编译错误,obj必须引用已存在的对象
{
public:
    int value;
    Object& obj;
};
class Object//正确,指针起初没有指向任何对象
{
public:
    int value;
    Object *pobj;
};
class Object//正确,静态成员不属于对象,构建obj对象只有value,没有内部对象
{
public:
    int value;
    static Object obj;
};
#include
using namespace std;

class Int
{
private:
	mutable int value;//如果在类的非静态成员前面加mutable关键字之后,可以不被const限制
	static int num;
public:
	Int(int x = 0) :value(x) {}
	void fun() const
	{
		num += 100;
		value += 10;//error不允许改变
	}
};
int Int::num = 0;
int main()
{
	Int a;
	a.fun();
}
3.5 同全局变量相比,使用静态数据成员有两个优势
  • 静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其他全局名字冲突的可能性。

  • 可以实现信息隐藏,静态成员可以是private成员,而全局变量不能。

3.6 静态方法

函数成员说明为静态,将与该类的不同对象无关。静态函数成员的调用,在对象之外可以采用下面的方式:类名::函数名或对象名.函数名;

与静态数据成员相反,为使用方便,静态函数成员多为公有。


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1022321.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号