我有一些代码可以生成这样的小部件:
std::unique_ptr<Widget1> Widget1::Create()
std::unique_ptr<Widget2> Widget2::Create()
现在我有另一段代码,需要使用Widget1
和Widget2
。我希望它有一个类似的界面,但将小部件作为输入。
std::unique_ptr<Widget3> Widget3::Create(<?> Widget1, <?> Widget2)
在内部,Widget3
应该包含一个引用,例如
class Widget3
{
public:
std::unique_ptr<Widget3> Create(<?> Widget1, <?> Widget2)
{
_widget1 = Widget1;
_widget2 = Widget2;
}
void doSomething()
{
std::cout << _widget1->hello() << _widget2->hello();
}
private:
<?> _widget1, _widget2
};
现在我考虑用std::shared_ptr
代替<?>
,因为这似乎是最理智的。然而我很困惑我应该如何传递它?
想法?
这里的诀窍是"关注点分离"。
对象的生存期与其实现是一个单独的问题。
CCD_ 6和CCD_ 7控制寿命。小部件n对象做事情。
如果你在代码设计中尊重这种关注点的分离,你的生活将是幸福的,你的程序永远不会出错,你的同事也会爱你:
#include <iostream>
#include <memory>
#include <string>
struct Widget1 {
std::string hello() { return "widget1"; }
};
struct Widget2 {
std::string hello() { return "widget2"; }
};
struct Widget3 {
// Widget3 objects share their components. This is now documented in the interface here...
Widget3(std::shared_ptr<Widget1> widget1, std::shared_ptr<Widget2> widget2)
: _widget1(std::move(widget1))
, _widget2(std::move(widget2))
{
}
void doSomething()
{
std::cout << _widget1->hello() << _widget2->hello();
}
private:
std::shared_ptr<Widget1> _widget1;
std::shared_ptr<Widget2> _widget2;
};
using namespace std;
auto main() -> int
{
// make a unique Widget3
auto w1a = make_unique<Widget1>();
auto w2a = make_unique<Widget2>();
// note the automatic move-conversion from unique_ptr to shared_ptr
auto w3a = make_unique<Widget3>(move(w1a), move(w2a));
// make unique widget3 that uses shared components
auto w1b = make_shared<Widget1>();
auto w2b = make_shared<Widget2>();
auto w3b = make_unique<Widget3>(w1b, w2b);
// make shared widget3 that shares the same shared components as w3b
auto w3c = make_shared<Widget3>(w1b, w2b);
return 0;
}
不需要使用static::create函数。它对对象的创建者强制执行内存模型。
如果你想强制执行一个内存模型(比如总是创建一个共享指针(,可以使用共享句柄pimpl习惯用法:来私下执行
// Widget4 objects have shared-handle semantics.
struct Widget4
{
private:
struct impl {
std::string hello() const { return "hello4"; }
};
public:
Widget4()
: _impl { std::make_shared<impl>() }
{}
std::string hello() const {
return _impl->hello();
}
private:
std::shared_ptr<impl> _impl;
};
如果小部件1和小部件2将仅作为小部件3的成员存在,并且以后不需要独立引用这些变量,则可以将它们作为值传递给Widget3::create()
std::unique_ptr<Widget1> Widget1::Create()// returns a unique_ptr to widget1
std::unique_ptr<Widget2> Widget2::Create()// returns a unique_ptr to widget2
std::unique_ptr<Widget3> Create(std::unique_ptr<Widget1> Widget1,
std::unique_ptr<Widget2> Widget2)
否则,如果您希望将Widget1和Widget2的对象保留为与Widget3共享的对象,请使用shared_ptr用于Widget1或Widget2