友谊从派生类方法到基类成员
friendship from derived class method to base class members
我想知道是否有一种方法可以使派生类的方法成为其基类的朋友。比如:
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'
我一整天都在挣扎。我发现所有关于友谊的东西都只使用分离类,不使用继承
没有直接的方法:Base
需要Derived::f
的定义,而Derived
也需要它的Base
类的定义。
但没关系,你不应该这样做,你可以,按优先顺序:
- 在
- 使整个
Derived
类成为好友(一般不需要) - 你可以使用一个中间的助手类,它只转发这个特定方法的调用,并赋予它友谊:
Base
类中提供受保护的访问器例子:
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);
}
处理这类问题的一种方法是应用"如果它是一个东西,那么它就是一个类"的规则。
@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
{};
我不知道是否有可能做到你想要的(尽管在我看来它应该是)——我很有兴趣看到其他的答案,如果它是——但是有一些其他的方法来实现你想要的。我假设您是在询问一般情况下的这种情况——也就是说,您也对可以有许多不同的派生类的情况感兴趣,并不是所有的派生类都需要,也不应该访问Base
的私有字段(否则您应该使这些字段当然是protected
)。
Derived
设置为Base
的朋友类,尽管这感觉像是一种hack(部分原因是它不允许对Base
进行任何关于Derived
的封装),并且在这里肯定不是最优的。
在我看来,在封装方面,一个更好的方法是创建一个外部的"自由"(非成员)函数,它是Base
的朋友(如果你也需要的话,也可能是Derived
)。这可以绕过循环编译器错误,但不幸的是仍然失去了作为"派生操作"的概念语义。
相关文章:
- 派生类看不到基类成员
- C++11: 如何访问派生类中的基类成员?
- Qml 未收到基类成员变量的更新值
- 指向从指针派生类成员函数的指针,指向基类成员函数
- 初始化基类成员 (c++) 的首选方法
- 访问多级复合关系中的基类成员
- 允许从特定派生类访问基类成员
- 在派生类的成员联合中包含继承的基类成员
- 由派生类设置的 constexpr 基类成员
- 从派生类调用的抽象基类成员函数
- 从抽象基类访问另一个基类成员
- C++派生类访问基类成员
- 不能引用派生模板类中的基类成员
- C2694 在析构函数上,当基类成员的析构函数具有非空 noexcept 说明符和主体时
- 在Visual Studio 2017中,通过扩展每个参数包来呼叫基类成员失败
- 在C 中访问带有不正确的下属的基类成员
- C++将基类成员链接到派生类成员
- 从基类成员函数返回派生类的实例
- 从指针到基类成员的模板推导
- 是否可以从派生类中排除基类成员?