【问题标题】:Inner class private member access and enclosing's friendness内部类私有成员访问和封闭的友好性
【发布时间】:2018-11-23 01:39:07
【问题描述】:

我正在尝试弄清楚如何使内部类型的 private/protected 成员对其封闭类可访问。

我的搜索让我遇到了很多关于如何从内部类 (e.g.) 访问 封闭成员 的问题,但这不是我需要的。其他很多帖子都遍历Java,这绝对不是我需要的。这是 C++。

考虑一下这个 MCVE:

#include <iostream>

struct bla
{
    bla( );
    ~bla( );

    class inner;

    inner *_inner;
};

class bla::inner
{
public:
    inner( )
    :   field( 13 )
    {}

private:
    friend struct bla;

    unsigned field;
};


bla::bla( )
:   _inner( new inner )
{}

bla::~bla( )
{
    delete _inner;
}

int main( )
{
    bla _bla;
    _bla._inner->field = 42;
    std::cout << "bla::_inner->field: " << _bla._inner->field << std::endl;
}

Live example

我能找到的唯一问题是C++ Outer class access Inner class's private - why forbidden,但建议的解决方案对我不起作用:

$ g++ -std=c++14 -Wall inner_class.cpp -o inner_class
inner_class.cpp: In function ‘int main()’:
inner_class.cpp:23:11: error: ‘unsigned int bla::inner::field’ is private
  unsigned field;
           ^
inner_class.cpp:39:15: error: within this context
  _bla._inner->field = 42;
               ^
inner_class.cpp:23:11: error: ‘unsigned int bla::inner::field’ is private
  unsigned field;
           ^
inner_class.cpp:40:54: error: within this context
  std::cout << "bla::_inner->field: " << _bla._inner->field << std::endl;

如何正确授予bla 访问field 的权限?我错过了任何愚蠢的细节吗?

提前致谢。

【问题讨论】:

  • 你不能。无论如何,不​​在main 的上下文中。 main 无法访问私有或受保护的字段,这是没有办法的。
  • "但建议的解决方案对我不起作用:" 这将表明这是一个 XY 问题。我建议您倒回一两个思考过程,然后说出您要解决的问题是什么。
  • @SombreroChicken 我认为你成功了。我刚刚修改了我的代码,发现我必须在“bla”中为我的“字段”提供访问器。请发布答案,以便我接受。
  • @SombreroChicken " main 无法访问私有或受保护的字段,没有办法解决这个问题" - 是的:friend int main();(我不是说你应该这样做,只是你可以

标签: c++ c++14 inner-classes friend


【解决方案1】:

您的代码正确授予bla 访问bla::inner 的私人成员所需的友谊。但是,您的问题是您没有访问 bla 中的私有成员(可以访问),而是在 main 中访问它,当然没有访问权限。

如果你想让bla能够访问bla::inner::field,你需要给bla一些访问它的功能。示例:

struct bla
{
    bla( );
    ~bla( );

    class inner;

    inner *_inner;

    void setInnerField(int val) { _inner->field = val; }
};

// The rest as before

int main( )
{
    bla _bla;
    _bla.setInnerField(42);
    std::cout << "bla::_inner->field: " << _bla._inner->field << std::endl;
}

另一方面,如果您想让所有外部代码(例如 main)访问该字段,只需将其公开即可。

【讨论】:

  • 非常感谢@Angew。当然,我还需要一个访问器来读取field。我很抱歉,但 Sombrero Chicken 的回应是第一位的,所以我认为考虑他的回应是公平的。再次感谢您。
【解决方案2】:

你不能。

您似乎认为因为_blabla 的对象,而bla 是外部类,您可以在bla 之外访问inner 的私有字段。事实并非如此。

访问修饰符作用于作用域,而不是你正在操作的对象。您可以在bla 的类主体中访问inner 的私有字段(在其方法等中)。不在它之外。

【讨论】:

    【解决方案3】:

    让 main 成为 bla::inner 的朋友应该可以。

        class bla::inner
    {
    public:
        inner( )
        :   field( 13 )
        {}
    
    private:
        friend struct bla;
        friend int main(); // Make main friend of bla
        unsigned field;
    };
    

    【讨论】:

    • 嗯,从技术上讲,我相信它确实有效,但并不那么漂亮。其他反应使它更干净。谢谢。
    猜你喜欢
    • 2015-04-16
    • 2016-07-10
    • 2014-08-21
    • 2011-01-14
    • 1970-01-01
    • 1970-01-01
    • 2021-08-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多