友元 friend机制允许一个类授权其他的函数访问类产生 对象 的非公有成员。
友元声明以关键字friend开头,它只能出现在类的声明中,它们不受其在类体中的public,private和protected区的影响。
不具有对称性、:A是B的友元,并不意味着B是A的友元。
不具有传递性︰A是B的友元,B是C的友元,但A不是C的友元。
不具有继承性: Base类型继承Object类型,如果Object类型是A的友元,但Base类型不是A友元。
#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;
}
运行结果
#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;
}
运行结果
#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;
}
外部函数友元,友元函数是一个外部函数,没有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;
}
友元函数不是类的成员函数,在函数体中访问对象的成员,必须用对象名加运算符"."加对象成员名。但友元函数可以访问类产生对象的所有成员,一般函数只能访问类中的公有成员。
友元函数不受类中的访问权限关键字限制,可以把它放在类的公有、私有、保护部分,但结果一样。
某类的友元函数的作用域并非该类作用域。如果该友元函数是另一类的成员函数,则其作用域为另一类的作用域,否则与一般函数相同。
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;
}
}
static可以修饰类的数据成员,也可以修饰类的函数成员。
由关键字static修饰类体中成员,成为类静态成员(static class member)。类的静态成员为其所有对象共享,不管有多少对象,静态成员只有一份存于公用内存中。静态数据成员被当作该类类型的全局对象。
int fun()
{
static int x = 0;//1.静态关键字修饰局部变量,生存期变为.data 2.当函数调动时,支队静态变量初始化一次 3.静态局部变量可以采取引用返回
int y = 10;
return x;
}
[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数据成员只能被声明为该类的指针
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();
}
静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其他全局名字冲突的可能性。
可以实现信息隐藏,静态成员可以是private成员,而全局变量不能。
函数成员说明为静态,将与该类的不同对象无关。静态函数成员的调用,在对象之外可以采用下面的方式:类名::函数名
或对象名.函数名
;
与静态数据成员相反,为使用方便,静态函数成员多为公有。