Наследование в C ++: Destructor не вызывается - PullRequest
0 голосов
/ 26 августа 2010

Я получил свой код, подобный следующему:

class TimeManager
{
public:
 virtual ~TimeManager();
};

class UserManager : virtual public TimeManager
{
public:
 virtual ~UserManager();
};

class Server : virutal public UserManager
{
 virtual ~Server();
};


CServer *pServer;

DWORD WINAPI ServerHelper(void*);

int main()
{
 //Create server
 CreateThread(NULL, 0, ServerHelper, NULL, 0, NULL);

 std::cin.get();

 //delete server
 delete pServer;

 std::cin.get();

 return 0;
}

DWORD WINAPI ServerHelper(void *v)
{
 pServer = new CServer;

 return 0;
}

Моя проблема в том, что мой деструктор сервера не будет вызван ... 1004

почему: / ... (Я написал выходные функции во всех трех классах, и конструктор сервера ничего не выводит, но оба других делают ... сразу после нажатия клавиши SECOND! ...(почему второе, а не сразу после удаления?)

Любые советы, подсказки, решения? ....

Я использую Visual Studio 2010

Ответы [ 5 ]

2 голосов
/ 26 августа 2010

Возможно, вы смотрите на неправильный класс сервера.Вы создаете экземпляр CServer, в то время как показанное вами определение класса предназначено для класса Server.(В качестве альтернативы это также может быть опечаткой в ​​вопросе.)

Кроме того, если вы слишком быстро нажмете на клавиатуре, до создания нового потока и запуска функции ServerHelper, вы можете выполнить delete до создания сервера.delete тогда просто увидит нулевой указатель и ничего не сделает, реальный объект сервера, созданный позже, не будет уничтожен.

1 голос
/ 26 августа 2010

Хорошо ... Я нашел решение проблемы:

Я запустил основной цикл из конструктора Серверы:

Server::Server()
{
MainLoop();       // <- Loop in there...
}

Я исправил это, запустив сервер вручную с помощью дополнительной функции, и теперь все в порядке: D ...

Спасибо всем, кто принимал участие:) ...

1 голос
/ 26 августа 2010

Используя эти определения классов (а остальные идентичны тем, которые вы опубликовали)

class TimeManager 
{ 
public: 
 virtual ~TimeManager() { cout << "~TimeManager" <<endl; }
};

class UserManager : virtual public TimeManager 
{ 
public: 
 virtual ~UserManager() { cout << "~UserManager" <<endl; }

}; 

class CServer : virtual public UserManager 
{ 
public: 
 virtual ~CServer() { cout << "~CServer" <<endl; }
}; 

Запуск дисплея

~CServer
~UserManager
~TimeManager

между первым и вторым нажатием клавиши ввода --- Точнокак и следовало ожидать.Кажется, ваша проблема в другом месте.

Обратите также внимание на то, что в классе CServer есть несколько опечаток, в частности, это иногда «CServer», а иногда «Server».Кроме того, «виртуальный» пишется неправильно, а dtor является приватным.Но любой из них помешал бы его компиляции, не вызвал бы ошибку времени выполнения.

Обратите также внимание, что код, как вы его разместили, не требует виртуального наследования.Либо вы без необходимости подбрасываете ключевое слово, либо ваши занятия более сложны, чем вы разрешаете.

0 голосов
/ 26 августа 2010

Итак, я попытался скомпилировать этот код, и он не компилируется, даже после исправления опечаток.Я исправил опечатки и сделал ваш Деструктор Сервера публичным, и все работает, как я и ожидал.сначала вызывается деструктор сервера, второй - UserManager, а третий - TimeMangager.

0 голосов
/ 26 августа 2010

CServer какой-то другой класс не определен вами?ваш класс определен как сервер, но вы создаете CServer.

...