销毁存储为void指针的类对象

时间:2016-03-25 23:35:20

标签: c++ pointers dll

我有以下问题。我有一个基类,就像一个接口,我有一个派生类,作为一个实际的实现。两者都有虚函数和虚析构函数。

现在我通过DLL中的基类创建一个指向派生类的指针,然后将该指针传递回主应用程序,其中它隐式地转换为" void *"。当应用程序结束时,通过调用指针上的delete来销毁指针。

不幸的是,删除void指针是一种未定义的行为,它永远不会击中任何析构函数(既不是基础也不是派生)并导致内存泄漏。所以我试图抛出它 - 不幸的是,这会导致崩溃。

该应用程序的当前设计如下:

  • 静态DLL - >基类
  • 动态DLL - >派生类
  • 动态DLL - >创建指针的地方
  • 主要应用 - >应该删除内存的地方。

这个想法是让主应用程序不依赖(链接)静态DLL,而只是根据需要加载动态DLL和实现。

现在为了解决所有问题,我看到了两种方式:

  1. 将基类放在主应用程序中,因为主应用程序应该管理指针并将其发送到我的应用程序周围的任何位置。然后派生类将从从主应用程序导出的类派生。
  2. 问题:我是否可以从主应用程序而不是DLL中成功导出类?该应用程序是跨平台的,因此我需要在Windows,Linux和Mac中执行此操作。

    1. 制作静态DLL动态DLL。然后希望我能通过适当的强制转换来删除void指针。
    2. 所以我的问题是:哪一种更可取?或许还有另一种,第三种方法来修复内存leak.crash。

      希望我清楚地解释了我的情况。

      编辑 :这是我目前的设计:

      静态库 - .dll / .a:

      class __declspec(dllexport) Base
      {
      public:
          Base();
          virtual ~Base();
          virtual Foo();
      };
      

      动态库1 - .dll / .so:

      class __declspec(dllexport) Derived1 : public Base
      {
      public:
          Derived1();
          virtual Derived1();
          virtual Foo();
      };
      

      动态图书馆2 - .dll / .so:

      class __declspec(dllexport) Derived2 : public Base
      {
      public:
          Derived2();
          virtual ~Derived2();
          virtual Foo();
      };
      

      这些库都与静态链接,因为它们依赖于它。

      动态库0 - .dll / .so:

      extern "C" __declspec(dllexport) Base *Bar()
      {
          Base *pb;
          if( <condition1> )
              pb = new Derived1();
          if( <condition2> )
              pb = new Derived2();
          return pb;
      }
      

      此库仅链接到dll1和dll2。他们不需要静态库中的任何东西。

      主要应用:

      class MainFrame
      {
      public:
          MainFrame();
          ~MainFrame();
          void Baz();
      private:
          void *m_pBase;
      };
      
      void MainFrame::~MainFrame()
      {
          delete m_pBase;
          m_pBase = NULL;
      }
      
      void MainFrame::Baz()
      {
          // load the library "Dynamic Library 0"
          // get the function pointer
          m_pBase = func();
      }
      

      因此,主要应用程序不能链接到任何东西 - 没有依赖性。仅使用动态加载dll0。并且dll0正在创建适当类型的对象。

1 个答案:

答案 0 :(得分:0)

将其作为指向基类的指针,并将析构函数声明为虚拟。