58

For a code like this:

class foo {
  protected:
    int a;
  public:
    class bar {
      public:
        int getA() {return a;}   // ERROR
    };
    foo()
      : a (p->param)
};

I get this error:

 invalid use of non-static data member 'foo::a'

currently the variable a is initialized in the constructor of foo.

if I make it static, then it says:

 error: 'int foo::a' is a static data member; it can only be initialized at its definition

However I want to pass a value to a in the constructor. What is the solution then?

2
  • 5
    why don't you move getA() to foo?
    – Eduardo
    Commented Mar 6, 2012 at 19:18
  • 4
    The code in your question has several problems that make it unclear what you're really trying to do. Please edit you question to indicate what your overall goal is. Commented Mar 6, 2012 at 19:32

5 Answers 5

50

In C++, unlike (say) Java, an instance of a nested class doesn't intrinsically belong to any instance of the enclosing class. So bar::getA doesn't have any specific instance of foo whose a it can be returning. I'm guessing that what you want is something like:

    class bar {
      private:
        foo * const owner;
      public:
        bar(foo & owner) : owner(&owner) { }
        int getA() {return owner->a;}
    };

But even for this you may have to make some changes, because in versions of C++ before C++11, unlike (again, say) Java, a nested class has no special access to its enclosing class, so it can't see the protected member a. This will depend on your compiler version. (Hat-tip to Ken Wayne VanderLinde for pointing out that C++11 has changed this.)

6
  • type of a is int. Why do you write foo *?
    – mahmood
    Commented Mar 6, 2012 at 19:27
  • I'm aware that a is of type int. I'm not sure what part of my answer confused you in that respect. :-/
    – ruakh
    Commented Mar 6, 2012 at 19:28
  • it says error: invalid conversion from 'foo*' to 'int' [-fpermissive]
    – mahmood
    Commented Mar 6, 2012 at 19:28
  • 2
    You should probably note that access rights have changed in C++11. Now the standard reads: "A nested class is a member and as such has the same access rights as any other member". Commented Mar 6, 2012 at 19:29
  • foo * means "a pointer to an object of type foo". I was assuming that you wanted each instance of bar to have an "owner" that's an instance of foo; in which case, it needs to have a pointer to that owner. Did I assume wrongly?
    – ruakh
    Commented Mar 6, 2012 at 19:29
10

In C++, nested classes are not connected to any instance of the outer class. If you want bar to access non-static members of foo, then bar needs to have access to an instance of foo. Maybe something like:

class bar {
  public:
    int getA(foo & f ) {return foo.a;}
};

Or maybe

class bar {
  private:
    foo & f;

  public:
    bar(foo & g)
    : f(g)
    {
    }

    int getA() { return f.a; }
};

In any case, you need to explicitly make sure you have access to an instance of foo.

4

The nested class doesn't know about the outer class, and protected doesn't help. You'll have to pass some actual reference to objects of the nested class type. You could store a foo*, but perhaps a reference to the integer is enough:

class Outer
{
    int n;

public:
    class Inner
    {
        int & a;
    public:
        Inner(int & b) : a(b) { }
        int & get() { return a; }
    };

    // ...  for example:

    Inner inn;
    Outer() : inn(n) { }
};

Now you can instantiate inner classes like Inner i(n); and call i.get().

1
  • @mahmood: b is the local argument of the constructor.
    – Kerrek SB
    Commented Mar 6, 2012 at 19:20
0

You try to access private member of one class from another. The fact that bar-class is declared within foo-class means that bar in visible only inside foo class, but that is still other class.

And what is p->param?

Actually, it isn't clear what do you want to do

4
  • there is no difference when I make a as public
    – mahmood
    Commented Mar 6, 2012 at 19:18
  • 1
    @mahmood within bar-class a doesn't exist at all, it's a part of foo-class. What are you trying to achieve?
    – Alecs
    Commented Mar 6, 2012 at 19:20
  • p->param is something that read a value from somewhere else and pass it to a. For example, in a file, I wrote '2'. the code reads that and pass to a
    – mahmood
    Commented Mar 6, 2012 at 19:23
  • @mahmood I asked because your code example isn't full, so maybe that's why what you want to do with your code isn't clear
    – Alecs
    Commented Mar 6, 2012 at 19:25
0

Your Question is not clear but there is use case when you will get this issue .

Invalid use of non-static data member.

When you are using "non-static data member in another class try to not use with scope resolution operator Example::className::memberData = assignivalue ; instead of above try to use object of className class; Example:: m_pClassName->memberData=assignValue;*

2
  • But, what if I'm trying to access a data member that is inherited and hidden by another member (such as a method, or another data member, shadowing the data member I'm trying to access by using the same name) ?
    – Michael
    Commented Nov 21, 2023 at 14:32
  • that also you can try using Class->MemberFunction->member(whatever) Commented Jan 11 at 9:19

Not the answer you're looking for? Browse other questions tagged or ask your own question.