21(2).继承与友元

继承与友元

引入: 友元关系不能继承,也就是说基类友元不能访问子类私有和保护成员,在有些情况下会有基类友元不能访问子类私有和保护成员这样的需求.
于是就有如下实现方式 :

//继承与友元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);

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值