CRTP 导致段错误
CRTP causing segfault
我有一个纯虚拟classInterface
:
class Interface {
public:
virtual ~Interface() noexcept;
virtual void open()=0;
virtual void close()=0;
protected:
explicit Interface(const string params);
string params_;
}
然后我有一个摘要 class,我在其中实现我的业务逻辑:
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
上调用关闭方法,然后在 this
:
上出现段错误
template<typename T>
void AbstractInterface<T>::close() {
static_cast<T *>(this)->close();
params_ = "";
}
这令人困惑,因为我已经创建了 class 的实例。 lldb 似乎确认:
AbstractInterface<SPInterface>::close(this=<unavailable>)
Letting this get out of scope calls the destructor AbstractInterface which in turn calls the close method on AbstractInterface and then it segfaults on this:
template<typename T>
void AbstractInterface<T>::close() {
static_cast<T *>(this)->close();
params_ = "";
}
您似乎正试图从基 class.
的析构函数中调用派生 class 的方法
这根本不安全,segfault 是可执行文件必须告诉您它不批准的方式。 :-)
即使 CRTP 允许您在(让我说)活对象 上调用属于派生 class 的成员函数,它也不会改变对象被破坏的方式。
不要忘记 bases 和 members 的销毁顺序与构造函数的完成顺序相反 .
我有一个纯虚拟classInterface
:
class Interface {
public:
virtual ~Interface() noexcept;
virtual void open()=0;
virtual void close()=0;
protected:
explicit Interface(const string params);
string params_;
}
然后我有一个摘要 class,我在其中实现我的业务逻辑:
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
上调用关闭方法,然后在 this
:
template<typename T>
void AbstractInterface<T>::close() {
static_cast<T *>(this)->close();
params_ = "";
}
这令人困惑,因为我已经创建了 class 的实例。 lldb 似乎确认:
AbstractInterface<SPInterface>::close(this=<unavailable>)
Letting this get out of scope calls the destructor AbstractInterface which in turn calls the close method on AbstractInterface and then it segfaults on this:
template<typename T>
void AbstractInterface<T>::close() {
static_cast<T *>(this)->close();
params_ = "";
}
您似乎正试图从基 class.
的析构函数中调用派生 class 的方法
这根本不安全,segfault 是可执行文件必须告诉您它不批准的方式。 :-)
即使 CRTP 允许您在(让我说)活对象 上调用属于派生 class 的成员函数,它也不会改变对象被破坏的方式。
不要忘记 bases 和 members 的销毁顺序与构造函数的完成顺序相反 .