Доступ частного члена внутреннего класса и дружелюбие вмещающего - PullRequest
0 голосов
/ 13 июня 2018

Я пытаюсь выяснить, как сделать член private/protected внутреннего типа доступным для включающего его класса.

Мой поиск привел меня ко многим вопросам о том, как получить доступ к включающему члену . из внутреннего класса ( например ), но это не то, что мне нужно.Многие другие сообщения пересекают 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;
}

Живой пример

Единственный вопрос, который я смог выяснить, рассматривая то, что мне нужно, это C ++ Доступ к внешнему классу Закрытый внутренний класс - почему запрещено , но предложенное решение не работает для меня:

$ 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?Я пропустил какую-нибудь глупую деталь?

Заранее спасибо.

Ответы [ 3 ]

0 голосов
/ 13 июня 2018

Вы не можете.

Вы, кажется, думаете, что, поскольку _bla является объектом bla, а bla является внешним классом, к которому вы можете обращаться к закрытым полям inner внеbla.Это не так.

Модификаторы доступа работают с областью, а не с объектами, над которыми вы работаете.Вы можете получить доступ к закрытым полям inner в теле класса bla (в его методах и т. Д.).Не за его пределами.

0 голосов
/ 13 июня 2018

Создание main как друга bla :: inner должно работать.

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

private:
    friend struct bla;
    friend int main(); // Make main friend of bla
    unsigned field;
};
0 голосов
/ 13 июня 2018

Ваш код правильно предоставляет дружбу, необходимую для 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) доступ к полю, просто сделайте его открытым.

...