C++ 销毁存储为空指针的类对象

C++ 销毁存储为空指针的类对象,c++,pointers,dll,C++,Pointers,Dll,我有以下问题。我有一个类似于接口的基类,还有一个作为实际实现的派生类。两者都有虚函数和虚析构函数 现在,我通过DLL中的基类创建一个指向派生类的指针,然后将该指针传递回主应用程序,在主应用程序中,它隐式地转换为“void*”。当应用程序结束时,通过对指针调用delete来销毁指针 不幸的是,删除一个空指针是一种未定义的行为,它不会命中任何析构函数(既不是基函数也不是派生函数),并导致内存泄漏。所以我试着投下它——不幸的是,这导致了崩溃 应用程序的当前设计如下所示: 静态DLL->基类 动态DL

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

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

不幸的是,删除一个空指针是一种未定义的行为,它不会命中任何析构函数(既不是基函数也不是派生函数),并导致内存泄漏。所以我试着投下它——不幸的是,这导致了崩溃

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

  • 静态DLL->基类
  • 动态DLL->派生类
  • 动态DLL->创建指针的位置
  • 主应用程序->应删除内存的位置
其思想是让主应用程序不依赖(链接)静态DLL,而只根据需要加载带有实现的动态DLL

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

  • 将基类放在主应用程序中,因为主应用程序应该管理指针并将其发送到我的应用程序周围的任何地方。然后,派生类将从从主应用程序导出的类派生
  • 问题:我可以从主应用程序而不是从DLL成功导出类吗?这个应用程序是跨平台的,所以我需要在Windows、Linux和Mac中这样做

  • 使静态DLL成为动态DLL。然后希望我能通过正确的施法删除空指针
  • 所以我的问题是:哪种方法更可取?也许还有第三种方法可以修复内存泄漏。崩溃

    希望我能清楚地解释我的情况


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

    静态库-.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();
    };
    
    class __declspec(dllexport) Derived2 : public Base
    {
    public:
        Derived2();
        virtual ~Derived2();
        virtual Foo();
    };
    
    extern "C" __declspec(dllexport) Base *Bar()
    {
        Base *pb;
        if( <condition1> )
            pb = new Derived1();
        if( <condition2> )
            pb = new Derived2();
        return pb;
    }
    
    动态库2-.dll/.so:

    class __declspec(dllexport) Derived1 : public Base
    {
    public:
        Derived1();
        virtual Derived1();
        virtual Foo();
    };
    
    class __declspec(dllexport) Derived2 : public Base
    {
    public:
        Derived2();
        virtual ~Derived2();
        virtual Foo();
    };
    
    extern "C" __declspec(dllexport) Base *Bar()
    {
        Base *pb;
        if( <condition1> )
            pb = new Derived1();
        if( <condition2> )
            pb = new Derived2();
        return pb;
    }
    
    这两个库都与静态库链接,因为它们依赖于静态库

    动态库0-.dll/。因此:

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

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

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

    尝试提供一个,有很多部分对我来说没有太大意义。@xvan,您知道是否可以从主应用程序而不是从DLL/so跨平台导出类吗?很难理解导出的含义。它看起来像一个插件/插件场景。如果您的所有dll在链接时都不可用,并且不共享公共基/接口,我会制作链接到dll的包装器,但有一个已知的接口。空指针是不需要的。@xvan,你能放一些伪代码吗?我不知道你的意思。Thx提前。顺便说一句,我说的“导出”是指代码使用的是“u declspec(dllexport)”。u declspec(dllexport)仅是windows。我的意思是[interface class(所有方法都是纯虚拟的)],[wrapper pimpl class(实现接口,包装静态dll)],在main上,您只需导入动态dll,构建包装器并将其转换到接口。不需要空指针。每个包装器只导出它的接口,每个包装器一个dll。然后主应用程序将链接到静态库,这是我想要避免的。可以从主应用程序导出类吗?@Igor我不明白这个问题。