我想知道是否有办法让派生类的方法成为其基类的朋友。类似的东西:
class Derived;
class Base
{
int i, j;
friend void Derived::f();
protected:
Base();
};
class Derived : public Base
{
public:
void f();
};
我得到的错误是:
error: C2027: use of undefined type 'Derived'
see declaration of 'Derived'
error: C2248: 'Base::i' : cannot access private member declared in class 'Base'
see declaration of 'Base::i'
see declaration of 'Base'
error: C2248: 'Base::j' : cannot access private member declared in class 'Base'
see declaration of 'Base::j'
see declaration of 'Base'
error: C2027: use of undefined type 'Derived'
see declaration of 'Derived'
我整天都在努力。我发现的关于友谊的一切都只使用分离的类,而不是继承。
答案 0 :(得分:2)
没有直接的方式:Base
需要Derived::f
的定义,而Derived
也需要定义Base
类。
但是没关系,你不应该这样做,你可以按照优先顺序:
Base
类Derived
班级成为朋友(一般不需要)示例here:
class Base;
class Derived;
class Helper final
{
friend class Derived;
public:
void f(Base* base);
private:
Helper() {}
};
class Base
{
int i, j;
friend class Helper;
protected:
Base() {}
};
class Derived : public Base
{
public:
void f();
private:
Helper helper;
};
void Helper::f(Base* base)
{
base->i = 10; base->j = 5;
std::cout << "Help !" ;
}
void Derived::f()
{
helper.f(this);
}
答案 1 :(得分:1)
解决这类问题的一种方法是应用规则“如果它是一个东西,那么它就是一个类。”
@quantdev解决方案就在这些方面。
基于评论:
假设我有两个类都派生自基类和 拥有相同的私人会员。为什么不保存一些代码 将该成员放在基类中并提供朋友访问权限 两个需要该成员的派生类。假设其他派生的 类根本无法访问该成员。这就是我的意思 试图实现
[我知道这不符合指定的问题,但可能是您需要的。]
我通过将公共元素分解为中间类来解决这个问题:
class Base
{
public:
Base();
virtual ~Base() = 0;
};
class Derived : public Base
{
public:
void f()
{
i = 1;
}
private:
int i, j;
};
class Foo : public Derived
{};
class Bar : public Derived
{};
class Fred : public Base
{};
答案 2 :(得分:0)
我不知道是否有可能完全按照自己的意愿行事(虽然在我看来应该是这样) - 而且我有兴趣看到其他答案显示它是如何 - 但是还有其他几种方法可以达到你想要的效果。我假设您一般都在询问这种情况 - 也就是说,您也对可能存在许多不同派生类的情况感兴趣,并非所有这些都需要,不应该访问{{1}的私有字段(当然,你应该创建这些字段Base
)。
首先,最简单的方法是将protected
朋友类设为Derived
,尽管这感觉就像是黑客(部分因为它不是允许对Base
进行Base
的任何封装,这绝对不是最佳选择。
在我看来,在封装方面更好的方法是创建一个外部“免费”(非成员)函数,它是Derived
的朋友(如果你是Base
也需要)。这解决了循环编译器错误,但遗憾的是仍然失去了作为“Derived操作”的概念语义。