Создание экземпляра базового класса внутри области и вызов вне области не работает

#c #pointers #inheritance

#c #указатели #наследование

Вопрос:

У меня возникла проблема с ошибкой сегментации со следующей основной функцией. «base» — это экземпляр базового класса, «baseOne» — это экземпляр производного класса. Когда я вызываю base->foo() внутри области, функция работает правильно, но когда я вызываю ее вне области, я получаю ошибку сегментации. Как я могу заставить base->foo() работать вне области?

main.cpp

 #include "Handler.hpp"
#include "Derived.hpp"

using namespace std;
int main(){
    Base* base;
    {
        Derived_factory factoryOne("Derived.so");
        std::unique_ptr<Base> baseOne = factoryOne.create();
        Base* b;
        b = baseOne.release();
        base=b;
        base->foo();
    }
    base->foo();
    return 0;
}
  

С другой стороны, следующий код работает, даже если он не подходит для моей программы.

 #include "Handler.hpp"
#include "Derived.hpp"

using namespace std;
int main(){
    Base* base;
    {
        Base* b = new Derived();
        base=b;
        base->foo();
    }
    base->foo();
    return 0;
}
  

Остальная часть кода приведена ниже.

base.hpp

     class Base {
    public:
        virtual ~Base() {}
        virtual void foo() = 0;
    };

    using Base_creator_t = Base *(*)();
  

derived.hpp

 #include "Base.hpp"

class A{
public:
    int k;
    void printsomething(){
        std::cout<<"class A "<<k<<std::endl;
    };
};

class Derived: public Base {
public:
    A a;
    void virtual foo(){
       std::cout<<"Hello Foo! Derived Class"<<std::endl;
       returnA();
    };
    void printA(){
      a.k = 10;
      a.printsomething();
    };
};
extern "C" {
  Base * create() {
    return new Derived;
  }
}
  

handler.hpp

 
#include <dlfcn.h>
#include "Base.hpp"
#include <iostream>
#include <memory>

class Derived_factory {
public:
    Derived_factory(char* path) {
        handler = dlopen(path, RTLD_NOW);
        if (! handler) {
            throw std::runtime_error(dlerror());
        }
        Reset_dlerror();
        creator = reinterpret_cast<Base_creator_t>(dlsym(handler, "create"));
        Check_dlerror();
    }

    std::unique_ptr<Base> create() const {
        return std::unique_ptr<Base>(creator());
    }

    ~Derived_factory() {
        if (handler) {
            dlclose(handler);
        }
    }

private:
    void * handler = nullptr;
    Base_creator_t creator = nullptr;

    static void Reset_dlerror() {
        dlerror();
    }

    static void Check_dlerror() {
        const char * dlsym_error = dlerror();
        if (dlsym_error) {
            throw std::runtime_error(dlsym_error);
        }
    }
};
  

Комментарии:

1. что такое Base_creator_t ?

2. @idclev463035818 Это тип, определенный в base.hpp и используемый в handler.cpp

3. о, верно, моя ошибка

4. Ваша main.cpp компиляция не выполняется, скорее всего, из-за отсутствия #include s.

5. в деструкторе Derived_factory, который вызывается в конце области FactoryONE, вы закрываете обработчик. Вы все еще получаете ту же ошибку, если прокомментируете dlclose (обработчик)? Похоже, что код производного класса находится в общей библиотеке, и вы пытаетесь вызвать его после выгрузки библиотеки.