友元函数是c++中一个重要的知识点,它使用起来方便,在操作符重载的时候也会用到。当然,友元机制破坏了封装机制,应当减少使用,但我们有时是不得不用。
我们定义类的时候,通常的习惯是一个头文件中定义一个类,很对集成开发环境可以帮助我们轻易的做到这点。但是,在这种情况下,将一个类的成员函数作为自己的友元函数,往往因为头文件包含的问题产生各种问题,编译不能通过。下面便展示一下一个完整的解决方案。
这里面涉及到两个类Date和Employ,我们要将Employ的成员函数作为Date的友元函数。
首先是Date头文件
//Date.h
#ifndef DATE_H_
#define DATE_H_
#include "iostream"
#include "Employ.h"
using namespace std;
class Date {
friend ostream& operator<<(ostream&,const Date&);
friend void Employ::setAnyDate(const Date&);
public:
Date();
Date(int y,int m,int d):year(y),month(m),day(d){}
// Date(const Date&);
void setDate(const Date&);
void display(void) const;
int getYear(void) const;
Date operator+(int) const;
private:
int year;
int month;
int day;
};
#endif /* DATE_H_ */
下面Date定义
#include "Date.h"
#include <iostream>
Date::Date(){
this->day=0;
this->month=0;
this->year=0;
}
void Date::setDate(const Date& d){
this->day=d.day;
this->month=d.month;
this->year=d.year;
}
void Date::display(void) const{
std::cout<<"year:"<<this->year<<"\t"<<"month:"<<this->month<<"\t"<<this->day<<std::endl;
}
int Date::getYear() const{
return this->year;
}
Date Date::operator+(int year) const{
Date d=*this;
d.year+=year;
return d;
}
ostream& operator<<(ostream& out,const Date& date){
cout<<date.year<<"年\t"<<date.month<<"月\t"<<date.day<<"日";
return out;
}
Employ头文件
#ifndef EMPLOY_H_
#define EMPLOY_H_
#include <iostream>
using namespace std;
class Date;
class Employ {
public:
Employ(string,string,string,const Date&,const Date&,int,double);
~Employ();
void setBirthday(const Date&);
void setJobYear(int);
void setSalary(double);
void addJobYear(int);
void display(void) const;
void setAnyDate(const Date&);
private:
string _number;
string _name;
string _id;
Date* _birthday;
Date* _engage;
int _job_year;
double _salary;
};
#endif /* EMPLOY_H_ */
Employ定义文件
#include "Employ.h"
#include "Date.h"
#include <string>
using namespace std;
Employ::Employ(string number, string name, string id,const Date& birthday,
const Date& engage, int job_year, double salary) {
_number = number;
_name = name;
_id = id;
_birthday = new Date(birthday);
_engage = new Date(engage);
_job_year = job_year;
_salary = salary;
}
Employ::~Employ(){
delete this->_birthday;
delete this->_engage;
}
void Employ::setAnyDate(const Date& date){
cout<<date.year;
}
void Employ::setBirthday(const Date& d) {
if(this->_birthday){
delete this->_birthday;
}
this->_birthday = new Date(d);
}
void Employ::setJobYear(int year) {
if(year<1 || year>12)
return;
this->_job_year=year;
}
void Employ::setSalary(double salary){
if(salary<0)
return ;
this->_salary=salary;
}
void Employ::addJobYear(int year){
if(year<0) return;
if((year+this->_birthday->getYear())>60){
cout<<"不能续聘"<<endl;
return;
}
this->_job_year+=year;
}
void Employ::display(void) const{
cout<<"工号:"<<this->_number<<endl;
cout<<"姓名:"<<this->_name<<endl;
cout<<"身份证:"<<this->_id<<endl;
cout<<"出生日期:"<<*(this->_birthday)<<endl;
cout<<"參加工作日期:"<<*(this->_engage)<<endl;
cout<<"工作年限"<<this->_job_year<<endl;
cout<<"月薪"<<this->_salary<<endl;
cout<<"到期年限"<<(*(this->_engage)+this->_job_year)<<endl;
}
以上代码 完美实现功能,Employ中定义的两个Date需要使用指针,防止出现Date未完成定义错误(incomplete field)