Find the answer to your Linux question:
Results 1 to 5 of 5
Hey guys, I'm having difficulty solving this problem. I hate to put code here but I'm doing this only as a last resort so please bare with me. #include <iostream.h> ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Linux Engineer
    Join Date
    Nov 2002
    Location
    Queens, NY
    Posts
    1,319

    inheritance


    Hey guys,

    I'm having difficulty solving this problem. I hate to put code here but I'm doing this only as a last resort so please bare with me.

    #include <iostream.h>

    class BaseClass {
    public:
    void f() const { cout << "BASE\n"; }
    };

    class DerivedClass : public BaseClass {
    public:
    void f() const { cout << "DERIVED\n"; }
    };

    void test( BaseClass * );

    int main()
    {
    BaseClass base;
    test( &base );

    return 0;
    }

    void test( BaseClass *basePtr )
    {
    DerivedClass *derivedPtr = NULL;

    // down casting
    derivedPtr = static_cast< DerivedClass * >( basePtr );
    derivedPtr->f();
    }

    Since DerivedClass used public inheritance to inherit BaseClass, an object of DerivedClass can be treated as a BaseClass. The opposite is not true but can be achieved using casting. Furthermore, we need to becareful in such instances when we dereference the LHS variable.
    This will print "DERIVED." I'm not understanding how this is happening since basePtr is pointing at a BaseClass object. BaseClass has one method f() which prints "BASE." In function test, we cast and assign basePtr to derivedPtr. I'm still thinking that derivedPtr is pointing at a BaseClass object. So, when we dereference method f(), shouldn't it print "BASE"? However, the result prints "DERIVED" which I don't understand.
    Can anyone help me understand this problem? Once again, I apologize for posting code but I didn't see a way to achieve clarity without the code.

    bp
    The best things in life are free.

  2. #2
    Just Joined!
    Join Date
    Nov 2002
    Location
    USA
    Posts
    99

    Downcasting or upcasting? That is the question.

    Hi,

    I'm bored so I'm answering your question, normally I'd advise reading a good C++ manual again, but hey you caught me on a good day.
    I don't like to do people's homework either, but I don't mind giving a few pointers now and then.

    Your code has several problems. Don't take offense, alright.

    First, I think you have a misunderstanding of the term 'downcast'.
    To downcast means to cast a pointer or reference into a class closer to the root of the inheritance hierarchy. Root being the starting point, right.
    What is your root in the example? BaseClass
    What is the class that you are casting to? DerivedClass
    Now what you are doing is the opposite of downcasting, you are upcasting.
    That's the first problem.

    Second, your code is doing exactly what you told it to do. Sorry, just like to say that. It's ignorant I know. Basically, you upcasted an instance of BaseClass to DerivedClass and called the f() member function. So, it runs the f() member function and prints 'DERIVED' which is exactly what you told it to do. If it printed 'BASE' I'd have to wonder about your computer's compiler. LOL

    Finally, you upcasted to a class which you did not allocate memory for. This is dangerous programming. This can lead to memory overwrites if you are not careful. If you don't understand what I mean, ask me to clarify that and I will.

    Does the above make sense? It also might help me to explain if I knew what the purpose behind your program was. Are you attempting to understand static casting or inheritance?

    Why, oh why didn't I take the blue pill?

  3. #3
    Linux Engineer
    Join Date
    Nov 2002
    Location
    Queens, NY
    Posts
    1,319

    the sky is clearing

    Slant6,

    You are absolutely correct about upcasting. That was my mistake. Upcasting is what I intend to say. I apologize about the confusion.

    You stated that I didn't allocate any memory for basePtr. If you look in the main function, I instantiated object "base" of class BaseClass. When I did that, it allocated space on the stack. I could have easily used the new operator to create this space on the heap but for this demonstration, I decided to go with the stack. Of course in JAVA this isn't possible. Every class must be instantiated on the heap using the new operator.

    OK, I think the sky is starting to clear up. I'm going to try and explain what I think is now happening. It seems that when I upcast, it treats the base object as a derived object. In reality, the pointer derivedPtr in function test is really pointing at object base of class BaseClass BUT since I casted it, the compiler is letting me get away with that statement. Now when I do:
    derivedPtr->f(), it'll call the method of DerivedClass because it thinks that its a DerivedClass. What if I changed DerivedClass to this?

    public DerivedClass : public BaseClass {
    public:
    DerivedClass( int = 0 ); // intializes attribute x to zero
    void f() const { cout << x << endl; }

    private:
    int x;
    };

    When I call method f inside function test, now it will need to print x. I presume that the output will be an undefined value. derivedPtr in function f is still pointing at object base. base DOES NOT have any member x and therefore x is never initialized anywhere causing it to print a value somewhere on memory. Is this correct?

    bp
    The best things in life are free.

  4. #4
    Just Joined!
    Join Date
    Nov 2002
    Location
    USA
    Posts
    99
    Yeah, you have got it.

    Your new example better demonstrates the danger I was trying to explain in my final point in the previous post. If you assigned a value to x you would overwrite memory and any number of things could happen. Now, in your program you are still safe because you declared x as a private variable, so obviously you could not write:
    derivedPtr->x = 2
    Your compiler won't let you get away with that, but if you declared x with public access, then you could write the above statement and overwrite memory that you did not allocate! This could cause your program to do some strange things if it overwrites certain parts of memory. I've made mistakes like that in past programs and it is sometimes very hard to debug. One of the flaws of C++, is that it lets you get away with doing that.

  5. #5
    Linux Engineer
    Join Date
    Nov 2002
    Location
    Queens, NY
    Posts
    1,319

    thanks

    Slant,

    Thanks dude. I hate leaving things unfinished and finally understanding this feels good.

    bp
    The best things in life are free.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •