我试图编写简单的父子类,并尝试使用智能指针。
我听说在构造函数中使用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<Base>
改为public enable_shared_from_this<Base>
,然后你就可以看到期望的输出结果。在线演示。 - rafix07