我有一个纯虚拟课程Interface
:
class Interface {
public:
virtual ~Interface() noexcept;
virtual void open()=0;
virtual void close()=0;
protected:
explicit Interface(const string params);
string params_;
}
然后我有一个抽象类来实现我的业务逻辑:
template<typename T>
class AbstractInterface : public Interface {
public:
void open() override;
void close() override;
void read_is_complete(const vector<byte_array>);
protected:
explicit AbstractInterface(const string params);
virtual ~AbstractInterface() noexcept;
}
然后是使用CRTP进行多态的接口的实现:
class SPInterface : public AbstractInterface<SPInterface> {
public:
explicit SPInterface(const string params);
virtual ~SPInterface() noexcept;
void open();
void close();
void read_is_complete(const vector<byte_array> data);
}
我有一个单元测试,我在其中创建SPInterface
的实例:
unique_ptr<Interface> intf;
intf.reset(new SPInterface("aaa"));
让这个超出范围会调用析构函数AbstractInterface
,它会在AbstractInterface
上调用close方法,然后在this
上调用segfaults:
template<typename T>
void AbstractInterface<T>::close() {
static_cast<T *>(this)->close();
params_ = "";
}
由于我已经创建了该类的实例,因此令人困惑。 lldb似乎证实:
AbstractInterface<SPInterface>::close(this=<unavailable>)
答案 0 :(得分:3)
让这个超出范围调用析构函数AbstractInterface,它反过来调用AbstractInterface上的close方法,然后对此进行段错误:
public void updateList(){
// fragment has a ListView - listview
// and an Adapter for the list - adapter
// add, remove, move, items in adapter
// and call notifyDataSetChanged();
adapter.notifyDataSetChanged();
}
您似乎正在尝试从基类的析构函数中调用派生类的方法。
这根本不安全, segfault 是可执行文件告诉您它不同意的方式。 : - )
即使CRTP允许您调用属于(我说)生活对象的派生类的成员函数,它也不会改变对象被破坏的方式。 /> 不要忘记基础和成员按照构造函数完成的相反顺序销毁。