我有一个函数SomeFunc
,其unique_ptr
类型A
作为参数。我想从类中调用SomeFunc
并将当前实例作为参数发送给函数。我使用以下,我得到一个分段错误。除了在这里使用原始指针之外,为什么会这样,并且有解决方法吗?
#include <iostream>
#include <memory>
using namespace std;
class A;
extern void SomeFunc(const unique_ptr<A>& Some1);
class A {
public:
A() {}
void Success() { cout << "Hey\n"; }
void Func() {
const unique_ptr<A> Some1(this);
SomeFunc(Some1);
}
};
void SomeFunc(const unique_ptr<A>& Some1) { Some1->Success(); }
int main() {
A a;
a.Func();
return 0;
}
答案 0 :(得分:2)
当unique_ptr超出范围时,它会尝试调用delete this
。但是this
没有动态分配,因此是seg错误。
你可以在SomeFunc之后立即调用Some1.release(),然后在unique_ptr超出范围之前,这是一个有点难看的黑客。
如果更改界面是可以接受的,更好的解决方案可能只是更改您的界面以接受const A&
,并将其称为SomeFunc(*this)
。
答案 1 :(得分:0)
你可以这样做 - 它只适用于API期望unique_ptr到完全抽象类的情况。基本上,您可以创建一个转发到您的实例的派生类...即给定
struct Abstract {
virtual void someFun() = 0;
};
和
T apiFun(unique_ptr<Abstract> ptr);
和你的班级
struct MyImpl : public Abstract {
virtual void someFun() { cout << "Hello world!" << std::endl; }
};
然后你可以
struct AbstractProxy : public Abstract {
Abstract* other;
AbstractProxy(Abstract* other): other(other) {}
virtual void someFun() { other->someFun(); }
};
- 当然这实际上不会删除你的课程。但是因为你实际上无法阻止你的类在堆栈上创建(在这种情况下,删除它会导致bad things
(TM)发生),你可能不想这样做。如果要确保始终删除已创建的实例,则可能不应公开构造函数,而是提供一个自由函数,该函数始终在堆上创建类的实例。或者你的unique_ptr期望能够删除你的班级。
在这种情况下,似乎API被破坏了。 unique_ptr
只能由相应实例的所有者持有,而且该功能似乎并不试图声明您的实例的所有权。