西宁市规划和建设局网站,wordpress插件开发,网站建设要,网络品牌营销C中#xff0c;允许一个类的非共有成员被这个类授予友元#xff08;friend#xff09;关系的全局函数#xff0c;另一个类#xff0c;或另一个类中的成员函数访问。友元不是一个类中的成员#xff0c;所以它们不受声明出现部分的访问权限#xff08;public#xff0c;p…C中允许一个类的非共有成员被这个类授予友元friend关系的全局函数另一个类或另一个类中的成员函数访问。友元不是一个类中的成员所以它们不受声明出现部分的访问权限publicprotectedprivate影响。友元函数友元函数是在类中用关键字friend修饰的非成员函数。友元函数可以是一个普通的函数,也可以是其他类的成员函数。虽然它不是本类的成员函数,但是在它的函数体中可以通过对象名访问类的私有和保护成员。友元类友元类是在类中用关键字friend修饰的另一个类的声明。那么这个友元类的所有成员函数都是这个类的友元函数在友元类的成员函数体内都可以通过对象名访问这个类的私有成员和保护成员。语法全局函数做友元void spell(){}
class Monster
{ //全局函数做友元friend void spell();
};
类做友元友元类class Skill{};
class Monster
{//友元类friend class Skill;
};类的成员函数做友元class Skill
{void spell(){}
};
class Monster
{//类的成员函数做友元friend void Skill::spell();
};example全局函数做Monster类的友元#include iostream
using namespace std;enum SKILL_TYPE
{BLOOD 0
};class Monster;//施法
void spellSkill(Monster src, Monster dest, const SKILL_TYPE skillType, const int skillVal);class Monster
{friend void spellSkill(Monster src, Monster dest, const SKILL_TYPE skillType, const int skillVal); //全局函数做友元public:Monster():m_monsterId(0), m_name(怪物), m_blood(0){}Monster(const int monsterId, const string name, const int blood):m_monsterId(monsterId), m_name(name), m_blood(blood){}Monster(const Monster m):m_monsterId(m.m_monsterId), m_name(m.m_name), m_blood(m.m_blood){}~Monster(){}void spell(Monster dest){spellSkill(*this, dest, BLOOD, 1000);}private:int m_monsterId; //怪物idstring m_name; //怪物名字int m_blood; //血量
};void spellSkill(Monster src, Monster dest, const SKILL_TYPE skillType, const int skillVal)
{switch (skillType){case BLOOD:{int blood 0;//destdest.m_blood - skillVal; //因为Skill类是Monster类的友元所以可以直接访问Monster类的非共有属性if (dest.m_blood 0)dest.m_blood 0;//srcsrc.m_blood skillVal; //因为Skill类是Monster类的友元所以可以直接访问Monster类的私有成员变量m_blood//因为Skill类是Monster类的友元所以可以直接访问Monster类的私有成员变量m_namecout src.m_name 攻击了 dest.m_name endl; cout src.m_name 的血量增加到 src.m_blood endl;cout dest.m_name 的血量减少到 dest.m_blood endl;break;}default:cout 技能类型未处理 skillType endl;}
}int main(int argc, char *argv[])
{Monster m1(10001, 雪女, 10000);Monster m2(10001, 紫衣仙子, 20000);m1.spell(m2);return 0;
}exampleSkill类做Monster类的友元#include iostream
using namespace std;enum SKILL_TYPE
{BLOOD 0
};class Monster;class Skill
{public:Skill():m_skillType(BLOOD), m_val(500){}Skill(const int skillType, const int val):m_skillType(skillType), m_val(val){}Skill(const Skill s):m_skillType(s.m_skillType), m_val(s.m_val){}~Skill(){}//施法void spell(Monster src, Monster dest);private:int m_skillType; //技能类型int m_val;
};class Monster
{friend class Skill; //友元类public:Monster():m_monsterId(0), m_name(怪物), m_blood(0), m_skill(BLOOD, 1000){}Monster(const int monsterId, const string name, const int blood, const int skillType, const int skillVal):m_monsterId(monsterId), m_name(name), m_blood(blood), m_skill(skillType, skillVal){}Monster(const Monster m):m_monsterId(m.m_monsterId), m_name(m.m_name), m_blood(m.m_blood), m_skill(m.m_skill){}~Monster(){}void spell(Monster dest){m_skill.spell(*this, dest);}private:int m_monsterId; //怪物idstring m_name; //怪物名字int m_blood; //血量Skill m_skill; //技能
};//施法
void Skill::spell(Monster src, Monster dest)
{switch (m_skillType){case BLOOD:{int blood 0;//destdest.m_blood - m_val; //因为Skill类是Monster类的友元所以可以直接访问Monster类的非共有属性if (dest.m_blood 0)dest.m_blood 0;//srcsrc.m_blood m_val; //因为Skill类是Monster类的友元所以可以直接访问Monster类的私有成员变量m_blood//因为Skill类是Monster类的友元所以可以直接访问Monster类的私有成员变量m_namecout src.m_name 攻击了 dest.m_name endl; cout src.m_name 的血量增加到 src.m_blood endl;cout dest.m_name 的血量减少到 dest.m_blood endl;break;}default:cout 技能类型未处理 m_skillType endl;}
}int main(int argc, char *argv[])
{Monster m1(10001, 雪女, 10000, BLOOD, 1000);Monster m2(10001, 紫衣仙子, 20000, BLOOD, 1000);m1.spell(m2);return 0;
}exampleSkill类的成员函数做Monster类的友元#include iostream
using namespace std;enum SKILL_TYPE
{BLOOD 0
};class Monster;class Skill
{public:Skill():m_skillType(BLOOD), m_val(500){}Skill(const int skillType, const int val):m_skillType(skillType), m_val(val){}Skill(const Skill s):m_skillType(s.m_skillType), m_val(s.m_val){}~Skill(){}//施法void spell(Monster src, Monster dest);private:int m_skillType; //技能类型int m_val;
};class Monster
{friend void Skill::spell(Monster src, Monster dest); //Skill类的成员函数做友元public:Monster():m_monsterId(0), m_name(怪物), m_blood(0), m_skill(BLOOD, 1000){}Monster(const int monsterId, const string name, const int blood, const int skillType, const int skillVal):m_monsterId(monsterId), m_name(name), m_blood(blood), m_skill(skillType, skillVal){}Monster(const Monster m):m_monsterId(m.m_monsterId), m_name(m.m_name), m_blood(m.m_blood), m_skill(m.m_skill){}~Monster(){}void spell(Monster dest){m_skill.spell(*this, dest);}private:int m_monsterId; //怪物idstring m_name; //怪物名字int m_blood; //血量Skill m_skill; //技能
};//施法
void Skill::spell(Monster src, Monster dest)
{switch (m_skillType){case BLOOD:{int blood 0;//destdest.m_blood - m_val; //因为Skill类是Monster类的友元所以可以直接访问Monster类的非共有属性if (dest.m_blood 0)dest.m_blood 0;//srcsrc.m_blood m_val; //因为Skill类是Monster类的友元所以可以直接访问Monster类的私有成员变量m_blood//因为Skill类是Monster类的友元所以可以直接访问Monster类的私有成员变量m_namecout src.m_name 攻击了 dest.m_name endl; cout src.m_name 的血量增加到 src.m_blood endl;cout dest.m_name 的血量减少到 dest.m_blood endl;break;}default:cout 技能类型未处理 m_skillType endl;}
}int main(int argc, char *argv[])
{Monster m1(10001, 雪女, 10000, BLOOD, 1000);Monster m2(10001, 紫衣仙子, 20000, BLOOD, 1000);m1.spell(m2);return 0;
}为什么要用友元如果需要在某个全局函数某一个类或某一个类中的成员函数访问另一个类的私有或保护成员变量又要求提高代码的执行效率减少系统开销我们可以选择让某个全局函数某一个类或某一个类中的成员函数为另一个类的友元friend但这会破坏另一个类的封装性。所以在实际的开发过程中我们应该按照实际需求选择是否用友元。友元的特性单向性比如上面的例子中Skill类是Monster类的友元但Monster类不是Skill类的友元友元不能被继承比如上面的例子中Skill类是Monster类的友元假如SceneSkill类是Skill类的子类SceneSkill类不是Monster类的友元。一般情况下用友元函数重载操作符