Using shared_ptr in dll-interfaces

前端 未结 4 1460
闹比i
闹比i 2020-12-02 19:12

I have an abstract class in my dll.

class IBase {
  protected:
       virtual ~IBase() = 0;
  public:
       virtual void f() = 0;
};

I wan

4条回答
  •  时光取名叫无心
    2020-12-02 19:50

    An answer to your first question: The virtual destructor in your dll is called - the information about its location is embedded in your object (in the vtable). In the case of memory deallocation it depends how disciplined the users of your IBase are. If they know they have to call Release() and consider that exception can bypass the control flow in an surprising direction, the right one will be used.

    But if CreateInterface() returns shared_ptr it can bind the right deallocation function right to this smart pointer. Your library may look like this:

    Destroy(IBase* p) {
        ... // whatever is needed to delete your object in the right way    
    }
    
    boost::shared_ptr CreateInterface() {
        IBase *p = new MyConcreteBase(...);
        ...
        return shared_ptr(p, Destroy); // bind Destroy() to the shared_ptr
    }                                         // which is called instead of a plain
                                              // delete
    

    Thus every user of your DLL is easily prevented against resource leaks. They never have to bother about calling Release() or pay attention to exceptions bypassing surprisingly their control flow.

    To answer your second question: The downside of this approach is clearly stated by the other answers: You're audience has to use the same compiler, linker, settings, libraries as you. And if they could be quite a lot this can be major drawback for your library. You have to choose: Safety vs. larger audience

    But there's a possible loophole: Use shared_ptrin your application, i.e.

    {
        shared_ptr p(CreateInterface(), DestroyFromLibrary);
        ...
        func();
        ...
    }
    

    Thus no implementation specific object is passed across the DLL boundary. Nevertheless your pointer is safely hidden behind the shared_ptr, who's calling DestroyFromLibrary at the right time even if func()'s throwing an exception or not.

提交回复
热议问题