C++: Accessing Grandparent Method
Asked Answered
D

6

6

Why doesn't this work, and what would be a good alternative?

class Grandparent
{
    void DoSomething( int number );
};

class Parent : Grandparent
{
};

class Child : Parent
{
    void DoSomething()
    {
        Grandparent::DoSomething( 10 ); // Does not work.
        Parent::DoSomething( 10 ); // Does not work.
    }
};
Dympha answered 15/1, 2011 at 23:30 Comment(0)
S
13
class Grandparent
{
protected:
    void DoSomething( int number );
};

class Parent : protected Grandparent
{
};

class Child : Parent
{
    void DoSomething()
    {
        Grandparent::DoSomething( 10 ); //Now it works
        Parent::DoSomething( 10 ); // Now it works.
    }
};

At a minimum it needs to look like that. Things are private by default when working with classes, this includes from subclasses.

http://codepad.org/xRhc5ig4

There is a full example that compiles and runs.

Scarlettscarp answered 15/1, 2011 at 23:35 Comment(8)
Note that members of a struct are public by default. In fact, the only difference between a class and a struct is that class members are private by default and struct members are public by default.Perse
yeah, I had just fixed the OP, and I just now compiled my example and it works... I need to look into what I'm doing wrong in my actual code. Thanks.Dympha
Are you getting a compile error? Or something breaking at runtime?Scarlettscarp
@Joshua I just compiled your example with GCC. I get the following error: temp3.cpp:(.text._ZN5Child11DoSomethingEv[Child::DoSomething()]+0x19): undefined reference to Grandparent::DoSomething(int)' temp3.cpp:(.text._ZN5Child11DoSomethingEv[Child::DoSomething()]+0x2a): undefined reference to Grandparent::DoSomething(int)'Dympha
Well, thats because the function itself doesn't actually exist. I didn't intend for it to be a valid example, just showing you what you need to fix. codepad.org/xRhc5ig4 There is a full exampleScarlettscarp
@Joshua duh! thanks for your help. sorry for the bad question and subsequent mistakes.Dympha
It's a reasonable enough question :) Glad you got it figured out.Scarlettscarp
For the record, the general concept of inheritance in object orientation is usually realised as public inheritance in C++. I would advise beginners to always use class Subclass : public Superclass.Grantinaid
R
0

I guess you code didn't compile - and principal source of error was missing return type specifier for method Child::DoSomething().

Rebba answered 15/1, 2011 at 23:53 Comment(4)
no that wasn't the problem. I just accidentally left it out in the example.Dympha
@Jay Ok, I saw that at the beginning. Next source of error is in the fact that public inheritance hides parent's private members in child's class so you need to elevate access level in parent - as in Joshua's answerRebba
don't you mean private inheritance?Scarlettscarp
@Joshua: Ooups, I overlooked that - and that is why you elevated and inheritance levelRebba
I
0
class Grandparent
{
    public:
    void DoSomething( int number ){
        cout<<number;
    }
};

class Parent : public Grandparent
{
    public:
    void DoSomething(int x){
        cout<<x<<'\n';
    }
};

class Child : public Parent
{
    public:
    void DoSomething()
    {
        Grandparent::DoSomething( 10 ); // works.
        Parent::DoSomething( 10 ); // works.
    }
};

Default inheritance type in c++ is private and also default member function access specifier in C++ is Private. So, you can't access private member of GrandParent class under any circumstances. You have make DoSomething() of GrandParent as either public or protected. And then mention appropriate inheritance type .

Islek answered 24/6, 2020 at 18:17 Comment(0)
B
0

(1) Yes, we can only access grandparents members in derived class when we inherit it either using public or protected access modifier.

(2) Base Class members declared as protected are inaccessible outside the class , but they can be accessed by any derived class of that class . When you inherit protected members of base class via public or protected access modifier , that data members access specifier is protected in the derived class .

(3) By default access modifier is private in C++ in inheritance which is in your given example . Since, you are trying to access private members of base class in child class , it is bound to give compile time error . Please read next point also.

(4) Base Class members declared as private are of course inherited to derived class . But , they are not accessible irrespective of the access modifier used while inheriting . It is the matter of availability v/s accessibility . Private members of base class are available to subsequent derived class but are not accessible . We can check this using sizeof(derived class object) operator after privately inheriting base class .

Lets discuss another thing .How do we access private members of base class ? Well , we can do that by using friend functions and pointers . But , Declaring Friend function inside base class depends on the creator of that base class . So , we wont talk about that in this post .

class Base
{
  private : 
           int x1,x2;
};

class Derived : public Base
{
     public : 
              int x3;
              void display(int *ptr)
              {
                   cout << "the value of x1 = " << *(ptr) << endl;
                   cout << "the value of x2 = " << *(ptr+1) << endl;
                   cout << "the value of x3 = " << *(ptr+2) << endl;
              }
};

int main()
{
    Derived d;
    int *ptr = (int *)&d.x3; // typecasting 

    *ptr = 3; // setting x3 as 3
     ptr--;
     
    *ptr = 2; // setting x2 as 2
     ptr--;
 
    *ptr = 1; // setting x1 as 1
     ptr--;

     d.display(ptr);
     return 0;
}

We have succesfully accessed private members of base class .

One more thing is there that i want to share is that : if we have a virtual grand parent class , we can directly call the grand parent constructor from child class . But in general it is not allowed to call grandparents constructor directly , it has to be called through parent classs . It is allowed only when virtual keyword is used .

Biagi answered 23/9, 2020 at 0:26 Comment(0)
S
0

Its Multi-Level Inheritance try mentioning the access specifier for your grandparent class.

Cause by default the access specifier is PRIVATE and we wont be able to access the private members of a parent class in the child class.

Selfregulated answered 18/8, 2021 at 3:13 Comment(0)
R
0

You have to add access specifier At second,sixth and tenth line.

class Grandparent
    { public:
    void DoSomething( int number);
     };

class Parent : public Grandparent{
  };

 class Child :public Parent{

    void DoSomething(){
        Grandparent::DoSomething( 10 );
        Parent::DoSomething( 10 );

    }
};
Reprehensible answered 27/5, 2022 at 13:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.