简体   繁体   English

C++ 如何在堆栈中存储唯一指针,并允许对象将指针从堆栈中取出(并获得所有权)

[英]C++ How to store a unique pointer in a stack, and allow objects to take the pointer out of the stack (and also gain ownership)

I am struggling with a failed unit test and cannot fix the problem.我正在为失败的单元测试而苦苦挣扎,无法解决问题。

I have an interface class "ContextObject", and a class "Context" that wraps a stack of unique pointers to "ContextObjects".我有一个接口 class “ContextObject”和一个 class “Context”,它包装了一堆指向“ContextObjects”的唯一指针。 For the test, I also have an implementation "FooContextObject" of the interface class.为了测试,我还有一个接口 class 的实现“FooContextObject”。 Shown Below:如下图所示:

struct ContextObject {
    virtual ~ContextObject() = 0;
};
ContextObject::~ContextObject() {}

struct FooContextObject : ContextObject {
    std::string name;
    FooContextObject(const std::string& name) : name(name) {}
    virtual ~FooContextObject() {}
};

The Context class is defined as follows:上下文 class 定义如下:

struct Context {
    std::stack<std::unique_ptr<ContextObject>> stack;
    void push(std::unique_ptr<ContextObject>&& t) { stack.push(std::move(t)); }
    std::unique_ptr<ContextObject> pop() {
        if(stack.empty()) {
            std::cerr << "Empty stack" << std::endl;
            exit(-4);
        }
        std::unique_ptr<ContextObject> ptr = std::move(stack.top());
        stack.pop();
        return std::move(ptr);
    }
    std::unique_ptr<ContextObject>& peak() { return stack.top(); }
};

And my test is:我的测试是:

void addToContext(Context& ctx) {
    auto obj = std::make_unique<FooContextObject>("foo");
    ctx.push(std::move(obj));
}

void useContextObject(Context& ctx) {
    ContextObject* a = ctx.pop().get();
    auto b = dynamic_cast<FooContextObject*>(a);
    std::cout << b->name << std::endl;
}

int main() {
    Context ctx;
    addToContext(ctx);
    useContextObject(ctx);
}

Can anybody let me know where I am going wrong, and help me get the code to pass the test?任何人都可以让我知道我哪里出错了,并帮助我获取代码以通过测试吗? Thanks.谢谢。

ContextObject* a = ctx.pop().get()

Here ctx.pop() returns a unique_ptr which gets destroyed at the end of the expression because it has no owner.这里ctx.pop()返回一个unique_ptr ,它在表达式末尾被销毁,因为它没有所有者。 You should assign jt to a unique_ptr to keep ownership.您应该将 jt 分配给unique_ptr以保留所有权。 Otherwise, you get a dangling pointer and b->name dereferences It, causing undefined behavior否则,你会得到一个悬空指针和b->name取消引用它,导致未定义的行为

Off topic note: consider changing the signature of push to题外话:考虑push送的签名更改为

void push(std::unique_ptr<ContextObject> t)

This way it is clear to the user of the API that the object passed to push is moved-from通过这种方式,API 的用户很清楚,传递给推送的 object 已从

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM