gpt4 book ai didi

c++ - 纯虚方法调用

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:12:29 25 4
gpt4 key购买 nike

我理解为什么从构造函数调用虚函数是不好的,但我不确定为什么定义析构函数会导致“调用纯虚方法”异常。该代码使用 const 值来减少动态分配的使用 - 也可能是罪魁祸首。

#include <iostream>
using namespace std;

class ActionBase {
public:
~ActionBase() { } // Comment out and works as expected

virtual void invoke() const = 0;
};

template <class T>
class Action : public ActionBase {
public:
Action( T& target, void (T::*action)())
: _target( target ), _action( action ) { }

virtual void invoke() const {
if (_action) (_target.*_action)();
}

T& _target;
void (T::*_action)();
};

class View {
public:
void foo() { cout << "here" << endl; }
};

class Button : public View {
public:
Button( const ActionBase& action )
: _action( action ) { }

virtual void mouseDown() {
_action.invoke();
}

private:
const ActionBase& _action;
};

int main( int argc, char* argv[] )
{
View view;
Button button = Button( Action<View>( view, &View::foo ) );
button.mouseDown();

return 0;
}

最佳答案

您有未定义的行为。由于 Button 的构造函数的参数是一个临时的 const&,它在该行的末尾,即构造函数完成后立即被销毁。在 Action 的 dtor 已经运行之后,您稍后使用 _action。由于这是 UB,允许任何事情发生,显然你的实现恰好做了一些略有不同的事情,这取决于你在 ActionBase 中是否有一个普通的 dtor。您会收到“纯虚拟调用”消息,因为该实现提供了直接调用 ActionBase::invoke 的行为,这就是当实现更改 Action 的 dtor 中对象的 vtable 指针时发生的情况。

我推荐使用 boost.function 或类似的“ Action 回调”库(例如,boost 有 signalssignals2)。

关于c++ - 纯虚方法调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1987602/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com