问题描述
晚上好。
在编写一些通用代码(至少在C ++ 11中)时,我遇到以下问题:
考虑一个名为I
的类,该类可以嵌套在各种类A,B,...,N中:
class A
{
protected:
friend class I;
class I
{
} i;
};
class B
{
protected:
friend class I;
class I
{
} i;
};
etc.
实际上I
是一种界面工具,会自动插入各种用户类A ... N中。不在乎这样做的原因...
然后有一个特定的类Z,目标是将任何I
声明为Z的朋友,以便任何I
和其他任何对象都不能使用Z,无论类A ... N( I
将嵌套在其中。
如果我这样声明:
class Z
{
friend class A; // <--- but I don't want to have to kNow this one
friend class I;
private: // creation and use of Z are restricted to tools like I
Z();
// other methods
};
然后它仅适用于A::I
:
可以从A::I::some_function()
构建和使用Z,
但不是B::I
或B ... N中的其他任何源。
没有friend class A;
,I
都无法访问Z。
- 如何使其具有通用性?
我正在寻找一种写模板朋友声明的方法,以声明对任何X::I
的访问权限,其中X是模板参数。
当然不是I
的模板参数,因为I
不是模板。
当然,我不想授予对任何类X的访问权限,以便任何X::I
也可以访问Z!
以下内容无效:
class Z
{
template< class X> friend class X::I;
...
};
=>错误:“我”不是“ X”的成员
从gcc版本5.4.0 20160609(Ubuntu 5.4.0-6ubuntu1〜16.04.11)
对正确语法有任何想法吗?我没有在参考文献中找到该用例...
非常感谢, 此致。
==================已在8月16日添加:精度:
I
持久地作为A
(或其他)的一部分而存在,而Z
是仅在I
的特定操作期间有效的工具,可能重复一次,然后创建一个新的Z
,使用它,然后每次都将其删除为I
方法的局部变量。
此外,Z
有一个有效载荷,因此我不想使其成为嵌入I
的每个对象的永久部分。例如,通过使Z
继承I
。
解决方法
通过使I
继承Z
,并使Z
成为抽象基类(因此不能直接访问),可能可以实现您想要的目标。
类似于:
class Z
{
virtual void __() = 0;
public:
virtual ~Z() = default;
void method() { std::cout << "Method from Z" << std::endl; }
};
class A
{
friend class I;
public:
class I : public Z
{
void __() final {}
public:
static Z *make_z();
} i;
};
Z *A::I::make_z()
{
return new I();
}
int main()
{
Z *z = A::I::make_z();
z->method();
return 0;
}