Jump to content
  • Advertisement
Sign in to follow this  
garyfletcher

Problem with virtual destructors - SOLVED

This topic is 4848 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi all. I have some classes based on a Inferface class: ITask:
class ITask
{
    public:
      ITask() : priority(5000), canKill(false)
      {
            	std::string msg = canKill?"TRUE":"FALSE";
            	
                //canKill=false;
                //priority=5000;
                
                std::cout << "ITask Default Constructor priority = " << priority << " canKill = " << msg << std::endl;
      }

      ITask(long p) : priority(p), canKill(false)
      {
            	std::string msg = canKill?"TRUE":"FALSE";
            	
            	std::cout << "ITask long Constructor priority = " << priority << " canKill = " << msg << std::endl;
      }

      ITask(long p, bool k) : priority(p), canKill(k)
      {
            	std::string msg = canKill?"TRUE":"FALSE";
            	
            	std::cout << "ITask long/bool Constructor priority = " << priority << " canKill = " << msg << std::endl;
      }

      virtual bool Start()=0;
      virtual void OnSuspend(){};
      virtual void Update()=0;
      virtual void OnResume(){};
      virtual void Stop()=0;

      bool canKill;
     long priority;
        
};


Derived class CPong:
Pong.h:

class CPongTask : public ITask
{
    public:
        CPongTask();
        CPongTask(long p);
        CPongTask(const CPongTask& rhs);
        CPongTask& operator=(const CPongTask& rhs);
        
        bool Start();
        void Update();
        void Stop(){};
        
        unsigned long size(){return sizeof(*this);}
        
    private:

        int callCount;

};

Pong.cpp:
#include <iostream>
#include "Pong.h"
#include "InputTask.h"
#include "App.h"
#include "GlobalTimer.h"

CPongTask::CPongTask() : ITask()
{
	std::cout << "CPongTask Default Constructor" << std::endl;
}

CPongTask::CPongTask(long p) : ITask(p)
{
	std::cout << "CPongTask Long Constructor" << std::endl;
}

CPongTask::CPongTask(const CPongTask& rhs) : ITask(rhs.priority,rhs.canKill)
{
	std::cout << "CPongTask Copy Constructor" << std::endl;
}

CPongTask::~CPongTask()
{
	std::cout << "CPongTask Destructor" << std::endl;
}

CPongTask& CPongTask::operator=(const CPongTask& rhs)
{
	std::cout << "CPongTask Assignment" << std::endl;
	
    if(this != &rhs)
    {
        priority = rhs.priority;
        canKill = rhs.canKill;
    }
    
    return *this;
}

bool CPongTask::Start()
{
    std::cout << "CPongTask Start()" << std::endl;
    callCount = 0;
            
    return true;
}
		
void CPongTask ::Update()
{
	std::cout << "CPongTask Update()" << std::endl;
	
	++callCount;
	
	std::cout << "callCount = " << callCount << std::endl;
	
	if (callCount == 100)
	{
		std::cout << "Killing all tasks" << std::endl;
		
        kernel::CKernel::Instance()->KillAllTasks();
	}
	
    return;
}


As you can see they don't really do much, am just trying to piece togther the foundations for a new engine. Anyhow, the problem arises on destruction. In their current form they work ok (or seem to..no memory leaks, according to my memory manager package). But if I make a virtual destructor in ITask and make the destructor virtual in CPong I get problems and the program crashes. It's taken me almost a week to find out that was the problem and I'm a little confused as to why it is so. Reading Effective C++, Mr. Meyers points out that base classes with virutal functions should have a virtual destructor...and who am I to argue. Any suggestions? [Edited by - garyfletcher on August 13, 2005 7:03:14 AM]

Share this post


Link to post
Share on other sites
Advertisement
I did do. Sorry didn't mention that in the text...will amend to make clearer

The source given shows what worked....without virtual destructors.

EDIT: actually, just checking the text I did mention that I made both destructors virtual...thanks anyhow..:)

Share this post


Link to post
Share on other sites
Did you give ITask's destructor an implementation, too? It *will* be called at destruction, and if it doesn't exist Bad Things happen...

So, either do this:

class Task
{
public:
virtual ~Task() { } // just leave empty if no cleanup required
};


Or this:

class Task
{
public:
virtual ~Task() = 0;
};

// Stuff

Task::~Task() { } // Yes, pure virtual functions can have an implementation

Share this post


Link to post
Share on other sites
Have located the problem...it wasn't an issue with the virtual destructors...sorry for wasting your time.

Problem was that I was deleting the same object twice...thanks for taking a look anyway.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!