Solved

tiny inheritance problem

Posted on 2004-08-04
16
221 Views
Last Modified: 2013-11-20
i recently came across this one, while designing class hierarchy describing plane figures with a number of vertices. id like to have in the base class some protected members defining the center of the figure and stuff, and to be able to access them freely form the derived objects, in order to perform some calculations.  
anyway, this doesnt work:
....................................................................................................
class base{   protected: int i;   };

class derive : public base{
public: void do_i (base* b) { b->i = 2004; }
};

int main(){
  base b;
  derive d;
  d.do_i(&b);
}
.......................................................................................................
the only way is to write

void do_i (base* b) { reinterpret_cast<derive*>(b)->i = 2004; }

which is probably not safe, and its definitly ridiculous in the contex:

circle c;
square b;
b.intersect_with(&c);

....reinterpret_cast<square*>(circle)->center... //hehe:)

so, can u explain to me whats happaning and sugest more sutable design?
thanks
0
Comment
Question by:podoboq
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 6
  • 2
16 Comments
 
LVL 13

Expert Comment

by:SteH
ID: 11715709
Change it to

class base{   protected: int i;   };

class derive : public base{
public: void do_i () { i = 2004; } // i is private member of derived class.
};

int main(){
  base b;
  derive d;
  d.do_i();
}
0
 

Author Comment

by:podoboq
ID: 11715775
i need access from inside my object to  the "i" of another object derived from base
0
 
LVL 13

Expert Comment

by:SteH
ID: 11715780
OK this only works for the first case not for something like intersect.

You can't access a protected or private member of another object inside a function.
In
 intersect_with (&c); // here c is not part of your object. Using inheritance you can use in your object the functions and variables of your base.
Circle and sqare seems both to be derived from some more general base which defines the variable center. When creating a derived object it will create a base object with full access to it.

I guess it would be easier to create a friend function intersect (base* b1, base* b2) which can then access private member of either object. This function is not necessarily part of the base class.

Or can it be a base class member function as well? This depends on how the base shape class is defined.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:podoboq
ID: 11715869
hmm, assuming that this is okay:

class base{
public:
        do_i(base &b){b.i = 2005;}
protected:      
        int i;
};
...
base b1, b2;
b1.do_i(b2);

i still cant get it whats the problem with my case?
0
 

Author Comment

by:podoboq
ID: 11715886
(note, that reinterpret_cast<derived*>(base) seems to do the job)
0
 
LVL 13

Expert Comment

by:SteH
ID: 11715964
How do you want to use the intersect function. It seems related to operator += and operator + overloading for self written classes. Both need access to (normally) private members of either object. operator += is a member function acting on one of the objects. Operator + is returning a new object which is created from the result using both objects. So in general I don't see any reason that the original part should not work.
0
 

Author Comment

by:podoboq
ID: 11716035
exactly!
why this mechanism is not workin with inheritance?
0
 
LVL 13

Expert Comment

by:SteH
ID: 11716084
It might be necessary to make the function friend to both base and derived class. Or does it suffice to be friend of the base? I am not sure whether friendship is inherited.

But it seems that you use intersect_with more as unary operator where the function would be a class member. Try to make that function virtual in the base and change its implementation in the derived classes as needed.

This last point might be the reason for your problem. At least in the first example do_i is a derived class member function which has restricted access to the base. But since your function is part of the architecture it should be a virtual member of the base.
0
 

Author Comment

by:podoboq
ID: 11717050
as far as i remember, frendship is not inhereted, anyway, i dont want friends.
sure, i can provide some get function(virtual otr not, it doesnt matter), even make members public and so on.
i just want my  base member variables accessed through derived objects.
0
 
LVL 13

Expert Comment

by:SteH
ID: 11723718
Have you tried making the function a virtual member of the base?
0
 

Author Comment

by:podoboq
ID: 11746259
i need the member variables, not functions
0
 
LVL 13

Expert Comment

by:SteH
ID: 11750519
I had a look at some application codes and there the friend function approach was used. It might be necessary since you not only want to access the private/protected members of the actual object but as well from a function parameter object.
0
 
LVL 9

Accepted Solution

by:
_ys_ earned 100 total points
ID: 11751814
> why this mechanism is not workin with inheritance?
C++ prevents access to protected/private members of other types.

Consider this:

class derived1 : public base { ... }
class derived2 : public base { ... }

int main ( )
{
    derived1 d1;
    derived2 d2;
    d2.do_i (&d1);
}

You certaintly wouldn't want derived2 modifying the protected member i of derived1. C++ prevents this. If you had two derived1 objects you would anticipate that C++ should be able to work it out. But that would involve it walking through object heirarchies *run-time* establishing if it's Ok to proceed or not, with impacts on performance. So it just doesn't !

You could add an overloaded do_i () function to your classes, allowing protected access to your base variables from within derived classes.

class base
{
protected:
    int i;

public:
    void do_i() { i = 512; }
};

class derive : public base
{
public:
    void do_i (base* b) { b->do_i(); } // invoke do_i () within the run-time context of b
    void do_i () { i = 1024; }
};

int main(int argc, char* argv[])
{
    base b;
    derive d;
    d.do_i(&b);

    return 0;
}

Sure there's an extra function call, but if it were inline that wouldn't make a difference. You could even make it virtual.
0
 

Author Comment

by:podoboq
ID: 11807619
sorry for my abscense, was on a little vacation
"You certaintly wouldn't want derived2 modifying the protected member i of derived1"
thats exactly what i firstly considered possible without reinterpret_casting the objects and so on :p
ill go without it, you're obviosyl right about "that would involve it walking through object heirarchies *run-time* establishing if it's Ok to proceed or not, with impacts on performance"
last question:

class base{   protected: int i;   };

class derive : public base{
public:
     void do_i (base* bp){
          derive* dp;
         (base*) dp = bp;
          dp->i = 2004;  //okay now. how is this exactly working?
     }
};

0
 
LVL 9

Expert Comment

by:_ys_
ID: 11808192
dp->i = 2004;  //okay now. how is this exactly working?
Both luck and a combination of what has been said before.

Luck, in that choosing to perform an implicit reinterpret_cast between base and derived pointer types has the potential of blowing up big time. Prefer the safer dynamic_cast instead. It'll even fail if it can't cast - rather than return garbage.

In this code i is being accessed from the scope of dp (derive*). Forget what dp really is (a cast of base*), it's dp, it derive*. Of course i as accessible from it's scope.

class base
{
protected:
    virtual ~base () {} //polymorphic type required to prevent compiler complaining

protected:
    int i;
};

class derive : public base
{
public:
    void do_i (base *bp)
    {
        derive* dp = dynamic_cast<derive*>(bp); //null pointer returned upon failure
        dp->i = 2004;  //okay now. how is this exactly working?
    //  bp->i = 2004;  //still doesn't work ...
    }
};
0
 

Author Comment

by:podoboq
ID: 11808415
thank you a lot, ys! think i got it, in fact i hoped for some sophisticated explanation involving compiler internals just for the sake of learning something new about c++ compiler, but its perfectly okay just that way:) i suddenly liked the idea of having derived objects modifying common base data very much, and for a while i had been thinkig it is quite a natural thing. this would had been solved my problem of manipulating objects without introducing friend functions and so on. alas...

0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question