Accessing a non static member of parent from a nested class's function
Asked Answered
M

3

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?

Meunier answered 1/7, 2014 at 17:7 Comment(1)
There is no A::func2, so I'm not sure what you expect int b = func2(a) to be calling.Luminescent
F
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.

Featherbrain answered 1/7, 2014 at 17:11 Comment(2)
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?Meunier
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.Monostylous
T
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.

Tegan answered 1/7, 2014 at 17:13 Comment(2)
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): #5309914Uteutensil
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.Monostylous
C
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.
}
Centi answered 1/7, 2014 at 17:45 Comment(2)
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.Meunier
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.Meunier

© 2022 - 2024 — McMap. All rights reserved.