【问题标题】:C++ Inheritance: Destructor does not get calledC++ 继承:不调用析构函数
【发布时间】:2011-04-04 09:47:18
【问题描述】:

我的代码如下:

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;
}

我的问题是 - 猜想 - 我的服务器析构函数不会被调用......

我无法想象,为什么:/...(我在所有三个类中都编写了输出函数,而服务器构造函数不输出任何内容,但其他两个都...在 SECOND 之后! key-hit...(为什么是第二个而不是删除后?)

任何提示、提示、解决方案?....

我正在使用 Visual Studio 2010

【问题讨论】:

  • pServer 变量是 Server 还是 CServer?
  • 修正您的拼写错误,然后也许有人可以回答您的问题。就目前而言,谁知道 wtf 正在进行,因为您发布的代码不可编译,因此显然不是您的问题的示例。
  • 我刚刚编译(修正错别字后)并运行了这个 VS2010 速成版。并且输出符合预期,即~CServer~UserManager~Testmanager
  • 尝试正确同步线程。等待创建的线程执行完ServerHelper,然后删除Server。
  • hmm... 服务器创建了 2 个不输出任何内容的工作线程,它们只是计算...服务器使用 WaitForMultipleObjects() 等待...

标签: c++ visual-studio-2010 destructor delete-operator


【解决方案1】:

您可能正在查看错误的服务器类。您创建CServer 的实例,而您显示的类定义是针对类Server。 (或者,这也可能是问题中的错字。)

另外,如果你敲键盘的速度太快,在创建新线程和运行ServerHelper函数之前,你可能会在创建服务器之前执行deletedelete 然后只会看到一个空指针,什么都不做,后面创建的真实服务器对象不会被破坏。

【讨论】:

  • 这只是一个错字...服务器类不是太大并且有一个记录器告诉我一切都已设置...并且正在运行...即使我等一下按,再等一分钟,再按第二次……它没有被调用……
【解决方案2】:

CServer 是不是你定义的其他类?您的类被定义为服务器,但您正在创建一个 CServer。

【讨论】:

    【解决方案3】:

    所以我尝试编译这段代码,但即使在修正了拼写错误之后,它也无法编译。我修正了错别字并公开了您的服务器析构函数,一切都按我的预期工作。首先调用 Server 析构函数,然后调用 UserManager,然后调用 TimeMangager。

    【讨论】:

    • 天啊...你真的认为我确实从我的真实代码中复制了上面的代码吗?...我只是手工将它写到这里...当然:构造函数和析构函数是公开的,他们有一个身体;),里面有一个std :: cout......请不要做多个答案......写cmets -------->“添加评论”
    • 好吧,如果您需要实际帮助,您应该发布将来可以使用的代码。在我修复代码后它按预期工作,所以我不确定你的代码有什么问题,特别是因为我不知道你的“真实代码”是什么样的。祝你好运。
    • @incubus:人们会帮助你处理你发布的代码。如果您发布无法编译的代码,那么这会使我们的任务变得更加困难。让你的例子简单、充分、正确,你会得到更好的答案。
    • 我找到了答案...将其发布在此问题的另一个答案中...谢谢您的帮助。
    【解决方案4】:

    使用这些类定义(其余与您发布的相同)

    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”。此外,“virtual”拼写错误,dtor 是私有的。但其中任何一个都会阻止它编译,而不是导致运行时错误。

    还请注意,您发布的代码不需要虚拟继承。您要么是在无谓地折腾关键字,要么是您的类比您说的更复杂。

    【讨论】:

    • @Incubbus 你会像上面的代码那样用 endl 刷新流吗?
    【解决方案5】:

    好的...我找到了问题的解决方案:

    我从 Servers 构造函数中启动了主循环:

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

    我通过一个额外的功能手动启动服务器来修复它,现在一切都很好:D...

    感谢所有参与的人:)...

    【讨论】:

      猜你喜欢
      • 2012-04-28
      • 2017-07-09
      • 2012-11-14
      • 2016-10-09
      • 2021-04-13
      • 1970-01-01
      • 2012-12-09
      • 2011-12-31
      • 2011-10-14
      相关资源
      最近更新 更多