Thread: Classes Help!!!

  1. #16
    Registered User
    Join Date
    Apr 2008
    Posts
    167
    Quote Originally Posted by Elysia View Post
    Are you aware of the purpose of virtual functions, especially virtual destructors?
    Not ~really~. All I know is that we have to have them.

    After all this, I still don't know what virtual functions are for, but I do know *how* to use them now =]

    And I can't get rid of the virtual destructor because we get marked down for warnings

  2. #17
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by citizen View Post
    I've typically treated class declarations as outlines of the implementation and rarely put the implementations in the class. This helps me separate implementation from the class design.
    Yes, it also helps when you want to modify the definition and if you just want to scan the definition, as well. Separating the two almost always results in advantages.

    Quote Originally Posted by Paul22000 View Post
    Not ~really~. All I know is that we have to have them.
    Virtual functions allow the compiler at run-time to what type of object it is that you're calling a function on. By doing this, it is possible to derive several classes from a common base class, and then call a virtual function inside the base class, and the compiler will actually call the same virtual function in the correct derived class:
    Code:
    class CBase { public: virtual void foo() { cout << "Base\n"; } };
    class CDerived1: public CBase { public: virtual void foo() { cout << "Derived1\n"; } };
    class CDerived2: public CBase { public: virtual void foo() { cout << "Derived2\n"; } };
    
    void foo(CBase& r)
    {
        r.foo();
    }
    
    int main()
    {
        CBase b;
        CDerived1 d1;
        CDerived2 d2;
        foo(b); // Prints "Base"
        foo(d1); // Prints "Derived1"
        foo(d2); // Prints "Derived2"
    }
    Consequently, the destructor is no different. The destructor is called when invoking delete on a pointer, so the correct destructor will be called (imagine renaming class member function foo to the destructor and changing the function foo to take a pointer (allocated with new) and calling delete inside).

    And I can't get rid of the virtual destructor because we get marked down for warnings
    Fair enough. It's recommended you have a virtual destructor for classes that contains virtual functions.
    Last edited by Elysia; 05-26-2008 at 12:12 PM.
    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.

  3. #18
    Registered User
    Join Date
    Apr 2008
    Posts
    167
    Quote Originally Posted by Elysia View Post


    Virtual functions allow the compiler at run-time to what type of object it is that you're calling a function on. By doing this, it is possible to derive several classes from a common base class, and then call a virtual function inside the base class, and the compiler will actually call the same virtual function in the correct derived class:
    Ahhh, that makes sense!

  4. #19
    Registered User
    Join Date
    Apr 2008
    Posts
    167
    Quote Originally Posted by Elysia View Post
    It's recommended you have a virtual destructor for classes that contains virtual functions.
    What's the downside to leaving it like it is?

    I have in the parent class:

    Code:
    virtual ~GraphObj() {};
    And that's it. Nothing in the base classes.

  5. #20
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You can just as well remove it because it serves no purpose.
    But if you don't want the warning, you can just leave it empty.
    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.

  6. #21
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    What's the downside to leaving it like it is?
    Read this FAQ on 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. #22
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Nothing in the base classes.
    Careful. "base class" and "parent class" are synonyms. The opposite is "derived" or "child class".
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  8. #23
    Registered User
    Join Date
    May 2008
    Posts
    53
    Quote Originally Posted by Elysia View Post
    You can just as well remove it because it serves no purpose.
    I think this is rather dangerous advice to give to someone who admits to "not ~really~" understanding virtual functions.

    Code:
    Base *p = new Derived();
    delete p;
    If Base doesn't have a virtual destructor, then ~Base gets called but ~Derived doesn't. Even if your ~Base doesn't do anything useful, someone else deriving from your Base might have a ~Derived which does, expecting it to be called.

    Compilers generate this warning because if your class has virtual functions, it is apparently intended to be derived from.

    --
    Computer Programming: An Introduction for the Scientifically Inclined

  9. #24
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    If Base doesn't have a virtual destructor, then ~Base gets called but ~Derived doesn't.
    In practice, yes, though by the rules of the C++ Standard it just results in undefined behaviour.
    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

  10. #25
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    And with multiple inheritance, it might well crash if you don't give it a virtual destructor:

    Code:
    struct B1
    {
      int d1, d2, d3;
      ~B1() {}
    };
    
    struct B2
    {
      int e1, e2, e3;
      ~B2() {}
    };
    
    struct D : B1, B2
    {
      int f1, f2, f3;
    };
    
    int main()
    {
      B2 *b2 = new D;
      delete b2;
    }
    Crashes on GCC:
    *** glibc detected *** ./multip: free(): invalid pointer: 0x000000000060201c ***

    The reason is that in GCC's internal model, the destructor returns a pointer to the actual start of the object, and that is passed to operator delete. If the destructor is not virtual, then you get the pointer to the B2 subobject, which is not the start of the object, and thus an address free() can't handle.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can you Initialize all classes once with New?
    By peacerosetx in forum C++ Programming
    Replies: 12
    Last Post: 07-02-2008, 10:47 AM
  2. im extreamly new help
    By rigo305 in forum C++ Programming
    Replies: 27
    Last Post: 04-23-2004, 11:22 PM
  3. Exporting VC++ classes for use with VB
    By Helix in forum Windows Programming
    Replies: 2
    Last Post: 12-29-2003, 05:38 PM
  4. Prime Number Generator... Help !?!!
    By Halo in forum C++ Programming
    Replies: 9
    Last Post: 10-20-2003, 07:26 PM
  5. include question
    By Wanted420 in forum C++ Programming
    Replies: 8
    Last Post: 10-17-2003, 03:49 AM