new operator

This is a discussion on new operator within the C++ Programming forums, part of the General Programming Boards category; Ques: when we declear our class object of base using new operator and initialize it address of drived class object,like: ...

  1. #1
    Registered User
    Join Date
    Jul 2005
    Posts
    10

    new operator

    Ques:
    when we declear our class object of base using new operator and initialize it address of drived class object,like:
    [code\]

    base *ptr=new drive;


    then we have to use virtual distuctore in that base class,why?
    give answere with example please.

  2. #2
    Registered User
    Join Date
    Apr 2003
    Posts
    2,662
    then we have to use virtual distuctore in that base class,why?
    So that the correct destructor is called. Whenever you use the "virtual" keyword, you are asking for "dynamic binding". Dynamic binding means that instead of calling the function that resides inside the class corresponding to the variable type, e.g. base, you want the function call to be directed to the function inside the class corresponding to the type of the object assigned to the pointer, e.g. drive.

    Normally to get dynamic binding, the functions have to have the same name in each of the classes, however destructors are an exception.

    Intuitively it should make some sense as well: you have a 'drive' object not a 'base' object, so you need to call the 'drive' destructor, which will automatically take care of the details.
    Code:
    #include <iostream>
    using namespace std;
    
    
    class Fruit
    {
    public:
    	virtual ~Fruit()
    	{
    		cout<<"Fruit destructor called."<<endl;
    	}
    };
    
    class Apple : public Fruit
    {
    public:
    	virtual ~Apple()
    	{
    		cout<<"Apple destructor called."<<endl;
    	}
    };
    
    class Strawberry : public Fruit
    {
    public:
    	virtual ~Strawberry()
    	{
    		cout<<"Strawberry destructor called."<<endl;
    	}
    };
    
    
    int main()
    {
    	Apple myApple;
    	Strawberry myStrawberry;
    
    	//When the program ends, the destructors will be called.
    
    	return 0;
    }
    Last edited by 7stud; 10-28-2005 at 02:51 AM.

  3. #3
    Bond sunnypalsingh's Avatar
    Join Date
    Oct 2005
    Posts
    162
    Nicely explained 7stud

    Nitin u can take alook at this also

    http://www.codersource.net/cpp_virtual_destructors.html

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,294
    7stud's almost nailed it. Only thing he left out is that;
    Code:
    base *ptr = new drive;
    delete ptr;
    yields undefined behaviour if base's destructor is not virtual. Some people will tell you that the above simply calls the base destructor. Those people are mistaken: although some compilers do that, they are not required to by the standard.

    The reason that it is undefined behaviour (rather than just specifying that only the base destructor is called) is that it is difficult to detect in general - if the destructor is not virtual, the compiler has no information to determine if a pointer to base is an instance of a derived class.

    Incidentally, in 7stud's example of fruit, virtual destructors are not actually required. The need for virtual destructors only arises in cases of "delete base_that_points_to_a_derived;"

  5. #5
    Registered User
    Join Date
    Apr 2003
    Posts
    2,662
    Incidentally, in 7stud's example of fruit, virtual destructors are not actually required. The need for virtual destructors only arises in cases of "delete base_that_points_to_a_derived;"
    Yeah, I really botched that example. Since there isn't a base class pointer, the example has nothing to do with polymorphism and virtual. Here is an amended program:
    Code:
    #include <iostream>
    using namespace std;
    
    class Fruit
    {
    public:
    	virtual ~Fruit()
    	{
    		cout<<"Fruit destructor called."<<endl;
    	}
    };
    
    class Apple : public Fruit
    {
    public:
    	virtual ~Apple()
    	{
    		cout<<"Apple destructor called."<<endl;
    	}
    };
    
    class Strawberry : public Fruit
    {
    public:
    	virtual ~Strawberry()
    	{
    		cout<<"Strawberry destructor called."<<endl;
    	}
    };
    
    int main()
    {
    	Fruit* pFruit = new Apple;
    	delete pFruit;
    
    	return 0;
    }
    Last edited by 7stud; 10-28-2005 at 12:38 PM.

  6. #6
    Unregistered User
    Join Date
    Sep 2005
    Location
    Antarctica
    Posts
    341
    I remember a few years ago that 5 of us developers spent like a week trying to figure out where this memory leak in our program was coming from. The application was very large and complex but we were sure that we covered all possibilities. It turned out that we forgot to make the destructor in one of our main base classes virtual.

  7. #7
    Registered User
    Join Date
    Apr 2003
    Posts
    2,662
    Quote Originally Posted by rockytriton
    I remember a few years ago that 5 of us developers spent like a week trying to figure out where this memory leak in our program was coming from. The application was very large and complex but we were sure that we covered all possibilities. It turned out that we forgot to make the destructor in one of our main base classes virtual.
    Hence the rule of thumb: "when you are using inheritance, as a matter of course, you should declare your base class destructors as virtual.

  8. #8
    Registered User
    Join Date
    Jun 2005
    Posts
    6,294
    Quote Originally Posted by 7stud
    Hence the rule of thumb: "when you are using inheritance, as a matter of course, you should declare your base class destructors as virtual.
    I'm glad you stated it as a "rule of thumb". The rule is often a good guideline, but there are cases where you don't need to follow it .... such as your first fruit example above.

    rockytriton's example actually exhibits one of the dangers of ANY code that exhibits undefined behaviour (whether that be "delete base_that_points_to_derived;" with base destructor non-virtual, or dereferencing a NULL pointer). People tend to assume that "undefined behaviour" means a blatant error (eg a segmentation fault, crashing the operating system, unintentionally reformatting a hard drive). The reality is that undefined behaviour can also mean very subtle and hard-to-find problems with symptoms such as "a memory leak, despite covering all possibilities".

  9. #9
    Registered User
    Join Date
    Jul 2005
    Posts
    10

    thanks

    i want to give thanks to every on ewho answered my question because now i understand the concept.




    thanksssssssssssss.

  10. #10
    Unregistered User
    Join Date
    Sep 2005
    Location
    Antarctica
    Posts
    341
    Quote Originally Posted by 7stud
    Hence the rule of thumb: "when you are using inheritance, as a matter of course, you should declare your base class destructors as virtual.
    Yes, since then I have always created a virtual destructor for EVERY class I create, no matter what! By the way, that was a pretty expensive 7 character error! If you imagine 5 developers working for a week, all who made about a 100k, that's about $1923 per week time 5 developers = $9,615!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Failure to overload operator delete
    By Elysia in forum C++ Programming
    Replies: 16
    Last Post: 07-10-2008, 01:23 PM
  2. Smart pointer class
    By Elysia in forum C++ Programming
    Replies: 63
    Last Post: 11-03-2007, 07:05 AM
  3. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  4. Operator Overloading (Bug, or error in code?)
    By QuietWhistler in forum C++ Programming
    Replies: 2
    Last Post: 01-25-2006, 07:38 AM
  5. operator overloading and dynamic memory program
    By jlmac2001 in forum C++ Programming
    Replies: 3
    Last Post: 04-06-2003, 11:51 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21