如何从父类是数据类的友元类的另一个派生类访问数据类的私有成员变量?
我有三个类:
数据持有者类 CDataHolder,它使用 Pimpl 模式
类CDataHolder { 民众: // ... 私人的: 朋友类CBase; 结构体PImpl; PImpl* iPimpl; };
基类CBase,需要访问CDataHolder中的iPImpl成员,因此是CDataHolder的友元类
类CBase: { 受保护: CDataHolder::Pimpl* getDataHolderPimpl(); };
CBase 的派生类CDerived,也需要访问相同的iPimpl 成员。 这里就出现了一个问题。 尽管派生类的父类是友元类,但派生类不能使用 iPimpl 成员。 像这样:
类CDerived:公共CBase { 民众: 无效 doSth() { CDataHolder::Pimpl *pImpl = getDataHolderPimpl(); // 这行会引发错误: //“从 CDataHolder 非法访问受保护/私有成员 CDataHolder::PImpl” } };
有很多派生类,因此对于每个派生类来说,在 CDataHolder 类中放置“friend class CDerivedXXX”行并不是一个好方法。 如何克服这个问题? 有一个更好的方法吗? 预先感谢。
I have three classes:
A data holder class CDataHolder, which uses a Pimpl pattern
class CDataHolder { public: // ... private: friend class CBase; struct PImpl; PImpl* iPimpl; };
A base class CBase, which need to access the iPImpl member in CDataHolder, so it is a friend class of CDataHolder
class CBase: { protected: CDataHolder::Pimpl* getDataHolderPimpl(); };
A derived class CDerived from CBase, which need to access the same iPimpl member also. Here occurs a problem.
The derived class cannot use the iPimpl member although its parent class is a friend class. like this:class CDerived : public CBase { public: void doSth() { CDataHolder::Pimpl *pImpl = getDataHolderPimpl(); // this line raises an error: // "illegal access from CDataHolder to protected/private member CDataHolder::PImpl" } };
There are plenty of derived classes, so it's not a good way for each derived class to put a "friend class CDerivedXXX" line in CDataHolder class.
How to overcome this issue? Is there a better way to do this? Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
由于您已在 CDataHolder 类的私有部分中声明了 struct PImpl ,因此只有 CDataHolder 的朋友才能访问它。 为什么不在公共部分中放置一个前向声明
struct PImpl
,或者在 CDataHolder 类之前放置一个更好?Since you have declared
struct PImpl
in the private part of CDataHolder class, only friends of CDataHolder can access the same. Why don't you put a forward declarationstruct PImpl
in the public section or even better before the CDataHolder class?朋友(理所当然)非常有限并且不能继承。 我讨厌提出这个问题,但也许 A) 您需要公共访问 PImpl 或其某些方面,或者 B) 您需要 DataHolder 类为您使用 PImpl 做一些事情。
Friend is (rightfully) very limited and can't be inherited. I hate to beg the question, but maybe either A) you need public access to PImpl or some aspect of it, or B) you need the DataHolder class to do something with PImpl for you.