继承与友元
引入: 友元关系不能继承,也就是说基类友元不能访问子类私有和保护成员,在有些情况下会有基类友元不能访问子类私有和保护成员这样的需求.
于是就有如下实现方式 :
//继承与友元example (1)
class Student;
class Person
{
public:
friend void Display(const Person& p, const Student& s);
protected:
string _name; // 姓名
};
class Student : public Person
{
protected:
int _stuNum; // 学号
};
void Display(const Person& p, const Student& s)
{
cout << p._name << endl;
cout << s._stuNum << endl; //error
}
void main()
{
Person p;
Student s;
Display(p, s);
}
以上代码是无法编译通过的
cout << s._stuNum << endl; //error
这一句代码会报错 : 错误(活动) E0265 成员 “Student::_stuNum” (已声明 所在行数:361) 不可访问
说明: 友元关系不能继承,也就是说基类友元不能访问子类私有和保护成员
解决办法很简单如下:
//继承与友元 right example (1)
//继承与友元 right example (2)
class Student;
class Person
{
public:
friend void Display(const Person& p, const Student& s);
protected:
string _name; // 姓名
};
class Student : public Person
{
public:
friend void Display(const Person& p, const Student& s);
protected:
int _stuNum; // 学号
};
void Display(const Person& p, const Student& s)
{
cout << p._name << endl; //当友元方法在基类和派生类中都有声明时,基类对象参数 可 通过友元函数访问基类的私有成员
//cout << p._stuNum << endl; //当友元方法在基类和派生类中都有声明时,基类对象参数 无法 通过友元函数访问派生类类的私有成员
cout << s._name << endl; //当友元方法在基类和派生类中都有声明时,派生类对象参数 可 通过友元函数访问基类的私有成员
cout << s._stuNum << endl; //当友元方法在基类和派生类中都有声明时,派生类对象参数 可 通过友元函数访问自己派生类的私有成员
}
void main()
{
Person p;
Student s;
Display(p, s);
}
只需要在派生类D中加上与基类友元函数的声明就行
//继承与友元 example (2)
class D;
class A
{
friend ostream& operator<<(ostream &out, const D &d);
public:
A(int a)
{
cout<<"A::A()"<<endl;
}
A(const A &a)
{
cout<<"A::A(const A&)"<<endl;
}
A& operator=(const A &a)
{
cout<<"A& A::operator=(const A&)"<<endl;
return *this;
}
~A()
{
cout<<"A::~A()"<<endl;
}
private:
int a_data = 1; //C++11
};
class D : public A
{
public:
D() : A(0)
{
cout<<"D::D()"<<endl;
}
~D()
{
cout<<"D::~D()"<<endl;
}
private:
int d_data = 2;
};
ostream& operator<<(ostream &out, const D &d)
{
cout<<d.a_data<<endl; //当友元方法只在基类中声明时,友元函数可访问基类的私有成员
cout<<d.d_data<<endl; //当友元方法只在基类中声明时,友元函数不能访问派生类的私有和保护成员
return out;
}
void main()
{
D d;
cout<<d<<endl;
}
以上代码是无法编译通过的
cout<<d.d_data<<endl; //error
说明: 友元关系不能继承,也就是说基类友元不能访问子类私有和保护成员
解决办法很简单如下:
//继承与友元 right example (2)
class D;
class A
{
friend ostream& operator<<(ostream& out, const D& d);
public:
A(int a)
{
cout << "A::A()" << endl;
}
A(const A& a)
{
cout << "A::A(const A&)" << endl;
}
A& operator=(const A& a)
{
cout << "A& A::operator=(const A&)" << endl;
return *this;
}
~A()
{
cout << "A::~A()" << endl;
}
private:
int a_data = 1; //C++11
};
class D : public A
{
friend ostream& operator<<(ostream& out, const D& d);
public:
D() : A(0)
{
cout << "D::D()" << endl;
}
~D()
{
cout << "D::~D()" << endl;
}
private:
int d_data = 2;
};
ostream& operator<<(ostream& out, const D& d)
{
cout << d.a_data << endl; //当友元方法只在基类中声明时,友元函数可访问基类的私有成员
cout << d.d_data << endl; //error当友元方法只在基类中声明时,友元函数不能访问派生类的私有和保护成员
return out;
}
void main()
{
D d;
cout << d << endl;
}
以上只需要在派生类D中加上与基类友元函数的声明就行
friend ostream& operator<<(ostream& out, const D& d);