Thread: Is there any hidden complication?

  1. #1
    Banned
    Join Date
    Nov 2007
    Posts
    678

    Is there any hidden complication?

    The following code, compiles & runs fine under MSVC .Net 2003, I just want to make sure, if, there is some complication here, like, construction/destruction being improper, or something like that, may be? I am not experienced enough, to judge myself.
    Code:
    class Base {};
    
    class Derived : public Base {
    public: Base* basePtr;
    };
    
    class AnotherDerived : public Base {};
    
    int main() {
        Derived derived;
        derived.basePtr = new AnotherDerived;
        return 0;
    }

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    For one thing, you fail to delete what you new. For another, you expose the internals of the Derived class to everyone, and require the user of the class to handle memory management of the internals. Base should have a virtual destructor, since it looks like you intend it to be a polymorphic base class.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Banned
    Join Date
    Nov 2007
    Posts
    678
    Thanks Light for so many useful points. Delete is easy, I will handle that later. Making them public , I just can't avoid. I have little idea about polymorphic nature of above definitions.

    Actually, there are many types (classes in my code), they all derive from, the same base class.
    In the above snippet, I could do any of these:
    Code:
    derived.basePtr = new Derived;
    derived.basePtr = new Base;
    derived.basePtr = new AnotherDerived;
    So, in a way, the basePtr can point to, virtually, all type of (class) objects that I have. Which will be a big plus. The thing is, I do not know enough, to say that, is it broken?

  4. #4
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    There nothing wrong with the example as is, but laserlight points out three potential problems with the design if this was part of a larger program.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  5. #5
    Banned
    Join Date
    Nov 2007
    Posts
    678
    Thank you Mir. But I did not understand his third point, polymorphic, what is wrong with my definitions, with regards to being polymorphic? Do I need polymorphism here?

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I suggest that you read When should my destructor be virtual?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Banned
    Join Date
    Nov 2007
    Posts
    678
    I read that link, I am getting it, a little, I understand the need for a virtual destructor now.
    See this code:
    Code:
    #include <iostream>
    using namespace std;
    
    class Base {
    public: ~Base() {
    		cout << "~Base()" << endl;
    	}
    };
    
    class Derived : public Base {
    public: Base* basePtr;
    public: ~Derived() {
    		cout << "~Derived()" << endl;
    	}
    };
    
    class AnotherDerived : public Base {
    public: ~AnotherDerived() {
    		cout << "~AnotherDerived()" << endl;
    	}
    };
    
    
    int main() {
    	Derived* derived = new Derived;
    	derived->basePtr = new AnotherDerived;
    	delete derived->basePtr;
    	delete derived;
    	return 0;
    }
    Output:
    ~Base()
    ~Derived()
    ~Base()

    I think that, because I did not make ~Base() into virtual, so, I invoked ~Base() where, technically, ~AnotherDerived() should have been invoked. I do not understand, why, two calls to ~Base(), though.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I do not understand, why, two calls to ~Base(), though.
    The derived class destructor invokes the base class destructor to destroy the base subobject.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I thought I taught you this before...
    Anyway, here goes again. The virtual destructor makes sure that delete can call the correct destructor. Each derived class calls its base class's destructor prior to destructing itself.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    Banned
    Join Date
    Nov 2007
    Posts
    678
    Finally. To make sure, that, I can assign all kind of derived (from Base) objects to the basePtr, and to make them delete properly, I just needed a virtual destructor in Base. Ok. Clear.

    But what would virtual ~Base() do? Especially, when, Base has nothing in it. It is just there, to make sure, all kind of Objects (derived from it) can be stored together.

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    What does a destructor do? Base does that same. Just because there's nothing in it that you can see doesn't mean it shouldn't be called.
    Just make a test class. Create no destructor. Allocate with new and delete with delete. Look as it calls the destructor even though there isn't one (empty).
    But if you start adding other objects in your class, then the destructor will start calling those destructors and destructing them, as well.
    The destructor performs work we do not see, that is necessary for the implementation to work.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Banned
    Join Date
    Nov 2007
    Posts
    678
    One more thing:

    Which should I put here,
    Code:
    virtual ~Base();
    Or    virtual ~Base() = 0;
    Or    virtual ~Base() {}
    Which is recommended?

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Elysia
    Each derived class calls its base class's destructor prior to destructing itself.
    Not "prior to" but "after" destroying itself (as in its own non-static member variables).

    Quote Originally Posted by manav
    Especially, when, Base has nothing in it.
    Why would Base have nothing in it? It looks like you are trying to create a cosmic hierarchy (i.e., there is one and only one base class, and every object is of a class derived from it, directly or indirectly), but even cosmic base classes in other programming languages have virtual member functions for derived classes to override. In C++, cosmic hierarchies are not the common practice, partially due to the power of the template mechanism.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    First and last is purely individual choice. Put it inside or outside the class?
    The second is if you want an abstract class - ie a class that you shouldn't be able to create (you can only create derived objects). Is this the case? Is it a bad thing™ to create Base? If yes, use the pure virtual function.

    Quote Originally Posted by laserlight View Post
    Not "prior to" but "after" destroying itself (as in its own non-static member variables).
    Ah, you're right. I didn't look at the code closely enough.
    Details, details. Who can remember them all?
    Last edited by Elysia; 05-30-2008 at 12:40 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Banned
    Join Date
    Nov 2007
    Posts
    678
    Bad. The first was just the same, as the last.
    Anyway, I will use virtual instead of using pure virtual which, requires more work in every derived class.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Hidden the information --Help!! (T.T)
    By nghoanglinh223 in forum C++ Programming
    Replies: 4
    Last Post: 04-01-2008, 09:07 AM
  2. Make a file hidden
    By manutd in forum C++ Programming
    Replies: 19
    Last Post: 11-05-2006, 11:27 AM
  3. Showing hidden files
    By hunterdude in forum Windows Programming
    Replies: 8
    Last Post: 06-10-2005, 11:02 AM
  4. can the procedure in the program be hidden?
    By Jasonymk in forum C++ Programming
    Replies: 7
    Last Post: 07-24-2003, 04:44 PM
  5. html form - writing ip to a hidden field
    By iain in forum A Brief History of Cprogramming.com
    Replies: 14
    Last Post: 11-16-2001, 03:29 AM