trikker
trikker

Reputation: 2709

Nested class' access to enclosing class' private data members

I'm having trouble implementing a nested class who's constructor is initialized with some of the enclosing class' private data members.

Example:

Header File:
class Enclosing {
   //...Public members
   //...Private members
   int x, int y
   class Inner; // Declaration for nested class
};

Impl. File:
// Stuff...
class Enclosing::Inner {
    explicit Inner() : foo(x), bar(y) // foo and bar are data members of Inner
    //...
};

I get an invalid use of non-static data member error. Is there something I'm missing when it comes to nested class access to its enclosing class' members?

Upvotes: 13

Views: 19148

Answers (3)

pankaj singh
pankaj singh

Reputation: 1

nested class can't access privet data member of enclosing class.compiler show a error if we try to access privet member of enclosing class, it can only access the public data member of enclosing class.....

Upvotes: -1

cdiggins
cdiggins

Reputation: 18203

The problem with your code is not visibility, as pointed out by AndreyT, but that an instance of the Inner class is not bound to a concrete instance of the Enclosing class. The In other words when constructing an Inner the compiler has no way of know which object to take the x and y values from.

You will have to explicitly provide an instance of the Enclosing class to the constructor of the Inner class as so:

class Enclosing
{
private:
  int x;
  int y;

  class Inner
  {
  private:
    int foo;
    int bar;

  public:
    explicit Inner(const Enclosing& e)
      : foo(e.x), bar(e.y) 
    { }
  };
};

Upvotes: 10

AnT stands with Russia
AnT stands with Russia

Reputation: 320371

Member x and y are non-static data member of Enclosing, which means that they only exist within a concrete object of Enclosing class. Without a concrete object, neither x nor y exist. Meanwhile, you are trying to refer to x and y without an object. That can't be done, which is what the compiler is trying to tell you.

If you want to initialize members Inner::foo and Inner::bar from x and y, you have to pass a concrete object of Enclosing type into the Inners constructor. For example

class Enclosing::Inner {    
  explicit Inner(const Enclosing& e) : foo(e.x), bar(e.y) 
    {}
  //...
};

Extra note: in the original C++98 the inner class has no special privileges is accessing the outer class. With C++98 compiler you'd either have to give the inner class the necessary privileges (friendship) or expose the members x and y as public. However, this situation was classified as a defect in C++98, and it was decided that inner classes should have full access to outer class members (even private ones). So, whether you have to do anything extra with regard to access privileges depends on your compiler.

Upvotes: 25

Related Questions