在一个项目中,我有一个 C-API,它使用 C 风格的函数指针作为回调。在其中一个回调中,我需要访问对象的私有函数Foo。请注意,API 调用是在我的类的函数内完成的。由于未显示代码,我有一个对象的句柄可供void*我访问。
除了构造容易出错之外,通过传递 lambda 作为回调,我可以访问对象的私有函数。这有点出乎我的意料,但对我来说很受欢迎。我还没有发现任何有关此行为的信息,所以我想请问是否有人可以解释为什么这是实际工作的。我不知道 lambda 正在捕获某些内容,但看起来这与实际的作用域有关。我正在使用 C++17 和 gcc 10.2。
这是一个示例代码块:
void TestFunc(void (*)(void*)) {
}
class Foo {
public:
Foo() {
TestFunc([](void* handle){
auto foo = reinterpret_cast<Foo*>(handle);
foo->BarFunc();
});
};
private:
void BarFunc() {};
};
Run Code Online (Sandbox Code Playgroud) 我知道我需要定义一个虚拟析构函数(即使我的类是最好的选择final)。就我而言,我使用类似 C 的结构(没有函数,没有默认值,只有普通成员)并使用继承来组成新结构。然后我存储一个指向基类的指针std::unique_ptr,让 RAII 完成剩下的工作。
我现在很好奇是否还需要显式添加虚拟析构函数以避免内存问题。
一个例子可能是:
#include <chrono>
#include <memory>
struct A {
std::chrono::milliseconds duration = std::chrono::milliseconds{-1};
int count = 0;
};
struct B {
int mode = 0;
};
struct C : public A, public B {
int foo = 1;
};
int main()
{
std::unique_ptr<A> base = std::make_unique<C>();
base.reset(); // I expect here that A,B and C are destructed properly
return 0;
}
Run Code Online (Sandbox Code Playgroud)