j4x
j4x

Reputation: 3716

Inner class private member access and enclosing's friendness

I am trying to figure out how to make a private/protected member of an inner type accessible to its enclosing class.

My search led me to many questions about how to access an enclosing member from the inner class (e.g.) but this is not what I need. Many other posts traverse Java, and this is definitely not what I need. This is C++.

Consider this 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

The only question I could find out treating what I need is C++ Outer class access Inner class's private - why forbidden, but the proposed solution does not work for me:

$ 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;

How to properly give bla access to field? Did I miss any silly detail?

Thanks in advance.

Upvotes: 2

Views: 121

Answers (3)

SaurabhS
SaurabhS

Reputation: 663

Making main as friend of bla::inner should work.

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

private:
    friend struct bla;
    friend int main(); // Make main friend of bla
    unsigned field;
};

Upvotes: 2

Hatted Rooster
Hatted Rooster

Reputation: 36503

You can't.

You seem to think that because _bla is an object of bla and bla is the outer class that you can access private fields of inner outside of bla. This is not the case.

Access modifiers work on scope, not on the objects you're operating on. You can access the private fields of inner in the class body of bla (in its methods etc). Not outside of it.

Upvotes: 1

Your code is correctly granting the friendship required for bla to access the private members of bla::inner. However, your problem is that you're not accessing the private member in bla (which would have access), you're accessing it in main, which of course has no access.

If you want bla to be able to access bla::inner::field, you need to give bla some functions for accessing it. Example:

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;
}

If, on the other hand, you want to give all outside code (such as main) access to the field, just make it public.

Upvotes: 4

Related Questions