友元就是允许其他类或函数访问类的非公有成员,打破了类的封装性,友元属性用friend来修饰
1.友元与函数
class friendclass
{
friend void seeprivatefunc();
public:
friendclass(){}
~friendclass(){}
private:
int a;
int b;
};
void seeprivatefunc()
{
friendclass fc;
fc.a=10;
fc.b=20;
cout<<fc.a<<fc.b<<endl;
}
int main(int argc, char const *argv[])
{
seeprivatefunc();
return 0;
}
上述代码将函数seeprivatefunc声明为友元,所以seeprivatefunc可以访问friendclass对象的私有变量,如果去掉friend,会出现访问权限的错误
2.友元与类
一个类可以是另一个类的友元类
class friendclass
{
friend class friendclass2;//友元类
public:
friendclass():a(5),b(10){}
~friendclass(){}
private:
int a;
int b;
};
class friendclass2
{
public:
friendclass2(){}
~friendclass2(){}
void func(const friendclass &t);
};
void friendclass2::func(const friendclass &t)
{
cout<<t.a<<t.b<<endl;
}
int main(int argc, char const *argv[])
{
friendclass t1;
friendclass2 t2;
t2.func(t1);
return 0;
}
friendclass2是friendclass的友元类,所以,friendclass2可以访问friendclass的非公有成员,因此void friendclass2::func(const friendclass &t)能成功打印a和b
一个类的成员函数也可以是另一个类的友元函数
上述代码还可以换一种写法,将friendclass2的成员函数func作为friendclass的友元,直接在func中就可以访问a和b
class friendclass2
{
public:
friendclass2(){}
~friendclass2(){}
void func();
};
class friendclass
{
friend void friendclass2::func();
public:
friendclass():a(5),b(10){}
~friendclass(){}
private:
int a;
int b;
};
void friendclass2::func()
{
friendclass t;
cout<<t.a<<t.b<<endl;
}
int main(int argc, char const *argv[])
{
friendclass2 t2;
t2.func();
return 0;
}
上述代码friendclass和friendclass2的位置变化了,friendclass2在前,因为friendclass中声明的友元必须得能被编译器找到,如果friendclass2在后面,会报错
提示无法找到friend void friendclass2::func();的声明
类的声明
可以把类的定义和声明分开,就就像函数的定义和声明分开,出现类的声明意味着只知道有一个这样名字的类,但是类里面的成员还是不清楚,也就是说,此时的类不完整,所以定义该类的指针
int main(int argc, char const *argv[])
{
class a;
a *p=nullptr;
return 0;
}
上述代码可以编译通过,但是不能对a的对象进行初始化,因为a是不完整的,只能定义指针
几乎所有的代码都是将类的声明放在头文件中,然后将该类的指针作为其他类的成员,上述代码只是为了演示
类直到被定义完成时,才能产生对象,在定义完成之前,类也是不完整的,所以,类的定义不能包含自身,但是可以包含自身的指针
class p
{
p t;
};
参考:
《C++ Primer》
欢迎大家评论交流,作者水平有限,如有错误,欢迎指出