鉴于此代码:
#include <iostream>
#include <memory>
class Controller;
class View {
public:
~View() {
std::cout << "Disposing View" << std::endl;
}
void SetObserver(std::shared_ptr<Controller> a_observer) {
observer = a_observer;
}
private:
std::shared_ptr<Controller> observer;
};
class Controller : public std::enable_shared_from_this<Controller> {
public:
static std::shared_ptr<Controller> Create(std::unique_ptr<View> view) {
//Can't use std::make_shared due to visibility rules :(
auto controller = std::shared_ptr<Controller>(new Controller(std::move(view)));
controller->Init();
return controller;
}
~Controller() {
std::cout << "Disposing Controller" << std::endl;
}
private:
std::unique_ptr<View> view;
explicit Controller(std::unique_ptr<View> a_view) : view(std::move(a_view)) {}
Controller(const Controller&) = delete;
void Init() {
view->SetObserver(shared_from_this());
}
};
int main() {
auto view = std::make_unique<View>();
auto controller = Controller::Create(std::move(view));
return 0;
}
我认为永远不会处理controller
对象(由running it确认)。
为了缓解此问题,将observer
变量设为weak_ptr
而不是shared_ptr
是否已足够?
除此之外,鉴于上述设计,我还应该注意其他任何潜在的问题吗?
答案 0 :(得分:3)
是的,正如您所说的std::weak_ptr
:
此外,
std::weak_ptr
用于破坏std :: shared_ptr的循环引用。
将成员更改为std::weak_ptr
并运行,产生
$ ./a.out
Disposing Controller
Disposing View
如果您需要,只需致电lock
(查看返回值),即可获得std::shared_ptr
( <\ n> <\ n> <}>
void doSomethingWithView() {
auto obs = observer.lock();
if(obs) {
// Still valid
}
}
可能的警告与std::weak_ptr
and multithreading有关。
答案 1 :(得分:2)
使用std::weak_ptr
可以,但鉴于View
的生命周期与其Controller
相关联,您只需存储指向Controller
的常规指针即可。这样,Controller
不必存储在std::shared_ptr
中,您可以摆脱std::enable_shared_from_this
两阶段初始化混乱。
出于安全原因,我还会将SetObserver
设为私有,并让Controller
成为View
的朋友。毕竟他们已经紧密结合了。
#include <memory>
class Controller;
class View {
friend class Controller;
private:
void SetObserver(Controller* a_observer) {
observer = a_observer;
}
private:
Controller* observer = nullptr;
};
class Controller {
public:
explicit Controller(std::unique_ptr<View> a_view) :
view(std::move(a_view)) {
view->SetObserver(this);
}
private:
std::unique_ptr<View> view;
};
int main() {
Controller controller(std::make_unique<View>());
}
作为旁注,您可以使用std::observer_ptr
表示您的意图成为标准的一部分。