【问题标题】:Why weak_from_this() always returns empty weak pointer? [duplicate]为什么weak_from_this() 总是返回空的弱指针? [复制]
【发布时间】:2023-03-12 00:36:01
【问题描述】:

我正在尝试编写简单的父子类,并尝试使用智能指针。

听说在构造函数中使用shared_from_this() 不好,所以我把它放在connect() 方法中。但是当我在这个方法中调用weak_from_this()时,它会返回空的弱指针。

我不知道我做错了什么,请帮忙:)

#include <iostream>
#include <memory>
#include <list>
#include <sstream>

using namespace std;

class Base : protected enable_shared_from_this<Base> {
public:
    weak_ptr<Base> parent;

    virtual void connect() {}
    virtual void replaceChild(shared_ptr<Base> oldChild, shared_ptr<Base> newChild) {}

    void setParent(weak_ptr<Base> parent) {
        this->parent = parent; // <-- passed to here, but always empty
    }

    virtual string toString() { return "Base"; }
};

class Item : public Base {
public:
    string toString() { return "Item"; }
};

class Item2 : public Base {
public:
    void connect() {
        if (auto parent = this->parent.lock()) {
            parent->replaceChild(this->shared_from_this(), make_shared<Item>());
        }
    }

    string toString() { return "Item2"; }
};

class Container : public Base {
public:
    list<shared_ptr<Base>> items;

    void connect() {
        for (auto &item : items) {
            weak_ptr<Base> ptr = this->weak_from_this();
            item->setParent(ptr); // <-- ptr is empty here, according to debugger breakpoint
            item->connect();
        }
    }

    void replaceChild(shared_ptr<Base> oldChild, shared_ptr<Base> newChild) {
        for (auto &item : items) {
            if (item == oldChild) {
                item = newChild;
                item->setParent(this->weak_from_this());
                item->connect();
                break;
            }
        }
    }

    string toString() {
        ostringstream ss;
        ss << "Container(";
        for (auto item : items) {
            if (item != *items.begin()) ss << ", ";
            ss << item->toString();
        }
        ss << ")";
        return ss.str();
    }
};

int main(int argc, char ** argv) {
    shared_ptr<Base> base = make_shared<Container>();

    if (auto cont1 = dynamic_pointer_cast<Container>(base)) {
        cont1->items.push_back(make_shared<Item2>());
        cont1->items.push_back(make_shared<Base>());
        cont1->items.push_back(make_shared<Container>());
    }

    base->connect();

    cout << base->toString() << endl;

    return 0;
}

预期输出:

Container(Item, Base, Container())

实际输出:

Container(Item2, Base, Container())

因为Item2 有空的parent

【问题讨论】:

  • protected enable_shared_from_this&lt;Base&gt; 更改为public enable_shared_from_this&lt;Base&gt;,然后您将看到所需的输出。 LIVE DEMO.
  • 开启警告;这段代码有很多问题。您可能希望使用“密码习语”使构造函数有效地私有化,并在类中提供静态工厂函数(否则人们可能会在堆栈上创建非共享对象或new 建立自己的非共享对象,并且该对象是自我感知的,它应该被共享)。 stackoverflow.com/questions/52179063/…

标签: c++ smart-pointers


【解决方案1】:

感谢@rafix07!!! 把protected改成public,就可以了!!!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-07
    • 1970-01-01
    • 2019-04-23
    • 2016-12-09
    • 1970-01-01
    • 1970-01-01
    • 2012-03-27
    • 1970-01-01
    相关资源
    最近更新 更多