#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 (обработчик)? Похоже, что код производного класса находится в общей библиотеке, и вы пытаетесь вызвать его после выгрузки библиотеки.