纯虚拟朋友班

Posted

技术标签:

【中文标题】纯虚拟朋友班【英文标题】:Pure Virtual Friend Class 【发布时间】:2015-11-23 21:20:33 【问题描述】:

我有一个类A,它有一个指向纯虚拟类B 的实例的指针。类C 派生自B,将自动拥有一个指向A(它的父级)的指针,并且需要访问它的成员。这可以通过在类A 中添加friend class C 来实现,但是对于从B 派生的每个类都需要这样做。

代码示例:

class A

public:
    friend class B; // This does not allow derived classes to be friends
    friend class C; // Now derived class B has access to `DoDomething`, but then this is needed for every single derived class

private:
    void DoDomething();
;


class B

    virtual void Tick() = 0;

protected:
    A* m_pointerToA; // <- is being set upon creating automatically
;


class C : public class B

    virtual void Tick()
    
        m_pointerToA->DoSomething();
    
;

有没有办法让B 的所有派生类都可以访问它们所指向的类A 的私有和受保护成员,而不必为每个成员添加friend class X

【问题讨论】:

friending 不是派生的,你不能。 @πάνταῥεῖ 然后我不得不将A的成员和方法公开,或者与我假设的每个派生类成为朋友? @Broxzier 不,你不是,因为B 可以通过它自己的受保护成员函数向其派生类公开需要友谊的功能。 @Broxzier 我提供了一个“小”解决方法here 如何摆脱朋友关系并用界面替换它们。 @πάνταῥεῖ 这很有趣,我一定会尝试抽象接口。谢谢! 【参考方案1】:

由于友谊不是继承的,你需要将所有依赖友谊的功能包装到基类B的受保护函数中。这将使所有派生自B 的类都可以访问需要“结交”的A 的功能:

class B 
    virtual void Tick() = 0;
protected:
    A* m_pointerToA; // <- is being set upon creating automatically
    void callDoSomething() 
        m_pointerToA->DoSomething();
    
;


class C : public class B 
    virtual void Tick() 
        std::cout << "Class C is about to tick..." << std::endl;
        callDoSomething();
    
;

class D : public class B 
    virtual void Tick() 
        callDoSomething();
        std::cout << "Class D has just ticked!" << std::endl;
    
;

这有效地将您的类层次结构中使用友谊的区域本地化为类B,这有助于封装。

【讨论】:

以上是关于纯虚拟朋友班的主要内容,如果未能解决你的问题,请参考以下文章

朋友班:不能访问私人会员?

华为机试真题 C++ 实现分班问题

华为 OD 机试真题 Python 实现分班问题

我将“朋友班 xxxxx”放在公共部分还是私人部分有区别吗?

我将“朋友班 xxxxx”放在公共部分还是私人部分有区别吗?

使用工厂朋友班分配新班,好的做法?