Solved

tiny inheritance problem

Posted on 2004-08-04
16
189 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
  • 8
  • 6
  • 2
16 Comments
 
LVL 13

Expert Comment

by:SteH
Comment Utility
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
Comment Utility
i need access from inside my object to  the "i" of another object derived from base
0
 
LVL 13

Expert Comment

by:SteH
Comment Utility
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
 

Author Comment

by:podoboq
Comment Utility
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
Comment Utility
(note, that reinterpret_cast<derived*>(base) seems to do the job)
0
 
LVL 13

Expert Comment

by:SteH
Comment Utility
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
Comment Utility
exactly!
why this mechanism is not workin with inheritance?
0
 
LVL 13

Expert Comment

by:SteH
Comment Utility
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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:podoboq
Comment Utility
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
Comment Utility
Have you tried making the function a virtual member of the base?
0
 

Author Comment

by:podoboq
Comment Utility
i need the member variables, not functions
0
 
LVL 13

Expert Comment

by:SteH
Comment Utility
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
Comment Utility
> 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
Comment Utility
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_
Comment Utility
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
Comment Utility
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

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
repeatSeparator  java  challenge 13 56
noX challenge 17 75
Problem to event 3 48
Can not remove SSL certificate on iPhone 6 - iOS10.2 12 81
This is to be the first in a series of articles demonstrating the development of a complete windows based application using the MFC classes.  I’ll try to keep each article focused on one (or a couple) of the tasks that one may meet.   Introductio…
Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
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.
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…

772 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

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now