【发布时间】:2016-06-08 18:11:12
【问题描述】:
我正在使用指向实现的习惯用法在不可变对象上实现装饰器模式。基本上我的设置是这样的
struct Object : ObjectBase {
void doSmth() override {
impl->doSmth();
}
// this is the function I'd like to implement
Object decorateWith(std::unique_ptr<ObjectDecorator>&&);
private:
std::unique_ptr<ObjectBase> impl;
};
struct ObjectDecorator : ObjectBase {
void doSmth() override {
// do some stuff
impl->doSmth();
// do some more stuff
}
private:
std::unique_ptr<ObjectBase> impl;
};
这里,decorateWith 函数应该有不同的行为,这取决于它被调用的对象是否是临时的。如果在非临时对象上调用它,它应该返回一个新的 Object 实例,我必须在其中制作当前 Object 的深层副本并将其存储在装饰器的 unique_ptr 中,而新 Object 本身的 impl 指针指向装饰器。 但是,如果在一个临时对象上调用 decorateWith,那么创建一个 ObjectDecorator 并将当前对象的 impl 指针移动到装饰器的 impl 指针中并让该对象指向新的装饰器就足够了。
为了强调我需要一种方法来从对 decorateWith 的调用中确定对象是否是临时对象,然后根据该检查的结果使用标记调度。这可能吗?
最好的 Xodion
编辑:示例调用者代码可能如下所示:
-
decorateWith 在非临时对象上调用
int main() { Object x{}; // this call does not modify x so it can be reused later Object y = x.decorateWith{std::make_unique<ObjectDecorator>()}; y.doSmth(); // do some other stuff here // here, if I had moved the impl-unique_ptr in the decorateWith // call this would now segfault since I'd call nullptr->doSmth(); x.doSmth(); } -
decorateWith 被临时调用
int main() { Object x = Object{}.decorateWith(std::make_unique<ObjectDecorator>()) .decorateWith(std::make_unique<ObjectDecorator>()) .decorateWith(std::make_unique<ObjectDecorator>()); // in this case it would be unneccessary to make a deep copy of all // previous instances so I'd like to only move the impl poiner every time x.doSmth() }
【问题讨论】:
-
你的解释最好用示例调用代码来支持。
-
您是要确定调用的
ObjectdecorateWith是临时的,还是decorateWith的参数是临时的? -
我只想在调用decorateWith的对象是临时对象时有条件地移动,否则进行深拷贝,所以它是关于如何检查对象是否是临时对象。正如下面的答案所示,不需要某种类型特征,因为可以使用 ref-qualifiers 重载。
标签: c++ rvalue temporary-objects