5

I tried snooping around for a similar question in the forum which could help me out without success.

I have a nested class in my C++ program. I am trying to access a variable of the parent class from a function in the nested class but am faced with the following error

ERROR: A non static member reference must be relative to a specific object

The variable I'm trying to access is protected and the nested class is public (and so is it's function)

Following is a code snippet depicting (or trying hard to) the scenario

Header File

class A
{
    protected:
        D x;

    public:

        int func1(int a);

        class B : protected C
        {
            int func2(int a);   
        }
}   

CPP File

int A::func1(int a)
{
    x = 5;
    B z;
    int b = z.func2(a);
}

int A::B::func2(int a)
{
    int c = x.getValue(a);      /* ERROR: A non static member reference 
                                   must be relative to a specific object */
}

From somewhere

A anObject;
anObject.func1(7);

The getValue() is a public function if that matters. Since I'm calling A's function through an object, and through that B's function, should that not be linked to that object and let me access that non static member?

42cornflakes
  • 193
  • 4
  • 15

3 Answers3

8

C++ internal classes are not like Java nested classes. There is no object inside another. They are just classes which namespace is another class, like Java static inner classes.

You have no access to the member x since it belongs to A, which is a completely unrelated class that has nothing (Inheritance, composite, etc) to do with B.

Dale Wilson
  • 9,166
  • 3
  • 34
  • 52
Manu343726
  • 13,969
  • 4
  • 40
  • 75
  • Makes sense. Thank you. My Goal here was to be able to access protected members of Class C inside functions of A. But since I did not want to extend A (no justification for the action though. Just felt the need to avoid it), I created a nested class B extending C assuming it will serve the same purpose. Apparently not. Is there a better way to approach this problem or should I just suck it up and extend class A? – 42cornflakes Jul 01 '14 at 18:23
  • 1
    At best, this lacks many important nuances. As of C++11, at least 3 years prior to this, nested classes _do_ get implicit `friend` access to _all_ members of the enclosing class - so long as they have some _reference_ to an instance of the parent. That was what the OP's error clearly pointed towards, simply needing to tell the compiler _which_ `A` to look in for `x`. – underscore_d Dec 04 '15 at 20:32
1

You are confusing inheritance with nested classes. A nested class B of a given class A is just a class within the A class namespace. An object of type B and an object of type A and not necessarily related to each other and do not automatically share member functions/objects.

Shoe
  • 74,840
  • 36
  • 166
  • 272
  • 1
    And you are confusing subsclassing with nested classes. Subclassing is a synonym for inheritance. For example, see the usage in this question (and many others): http://stackoverflow.com/questions/5309414/in-c-when-subclassing-why-sometime-i-need-to-add-virtual-key-word-to-overridde – Dale Wilson Jul 01 '14 at 17:26
  • but as of C++11, `B` _does_ automatically get access to all members of `A` as long as it has a reference to an instance. – underscore_d Dec 04 '15 at 20:34
0

When the line

int c = x.getValue(a);

is compiled, the compiler has to perform a name lookup for x. It can be a function variable, it can be a member variable of B, it can be a member variable of one of the classes from which B inherits, it can be a global variable, etc. Not sure why it chooses to print an error message about only A non static ember reference. Perhaps it's making some heuristic assessment by the fact that x is a member variable of A.

In your case, x is a member variable of A, which is not a parent class of B. B is simply a nested class in A. An instance of B can have access to the x member of an instance of A. Without an instance of A, access to x is not possible from A::B::func2(int a).

It's not clear from your code what your use case is. It seems you are just exploring C++.

Update

In response to From somewhere

You cannot call B::func2 from A::func1 without an instance of B. B is a nested class of A but an instance of A does not automatically have an instance of B. If you add

B b;

as a member variable in A, you can use:

int A::func1(int a)
{
    x = 5;
    int c = b.func2(a);
    return 0; // Make sure to return something sensible.
}
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Yes. I'm just exploring C++ and haven't presented the use case. I was trying out this idea which got me wondering why such an error occurred. I now understand the lack of direct relation between nested class and its parent. Thank you. – 42cornflakes Jul 01 '14 at 18:33
  • Agreed - with the edit. Something I overlooked. Corrected it in the code now. On a side note, if you are interested in the Use case, as to why I did what I did, I have mentioned it in the comment to Manu343726's answer. – 42cornflakes Jul 01 '14 at 18:47