为什么weak_from_this()总是返回空弱指针?

3

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

我听说在构造函数中使用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())

因为Item2parent为空。


9
protected enable_shared_from_this<Base> 改为 public enable_shared_from_this<Base> ,然后你就可以看到期望的输出结果。在线演示 - rafix07
打开警告;这段代码有很多问题。您可能想使用“密码识别法”使构造函数有效地私有化,并在类中提供静态工厂函数(否则人们可能会在堆栈上创建非共享对象或自己创建非共享对象,而且对象是自我感知的,应该是共享的)。 https://dev59.com/Eq7la4cB1Zd3GeqPYSql#52179200 - Eljay
1个回答

4
感谢 @rafix07!!! 将代码由 protected 改为 public,就可以运行了!!!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接