我有一个messenger依赖于printer实例的类.printer是一个多态基类,实际对象传递给messenger构造函数.
对于非多态对象,我只需执行以下操作:
class messenger {
public:
messenger(printer const& pp) : pp(pp) { }
void signal(std::string const& msg) {
pp.write(msg);
}
private:
printer pp;
};
Run Code Online (Sandbox Code Playgroud)
但是什么时候printer是多态基类,这不再起作用(切片).
考虑到这一点,做这项工作的最佳方法是什么
printer类不应该需要一个虚拟的clone方法(=需要依靠拷贝构造).我不想传递指向构造函数的指针,因为API的其余部分正在使用真实对象,而不是指针,并且在此处将指针作为参数会令人困惑/不一致.
在C++ 0x下,我或许可以使用a unique_ptr和模板构造函数:
struct printer {
virtual void write(std::string const&) const = 0;
virtual ~printer() { } // Not actually necessary …
};
struct console_printer : public printer {
void write(std::string const& msg) const {
std::cout << msg << std::endl;
}
};
class messenger {
public:
template <typename TPrinter>
messenger(TPrinter const& pp) : pp(new TPrinter(pp)) { }
void signal(std::string const& msg) {
pp->write(msg);
}
private:
std::unique_ptr<printer> pp;
};
int main() {
messenger m((console_printer())); // Extra parens to prevent MVP.
m.signal("Hello");
}
Run Code Online (Sandbox Code Playgroud)
这是最好的选择吗?如果是这样,那么在0x之前最好的方法是什么?有没有办法摆脱构造函数中完全不必要的副本?不幸的是,移动临时在这里不起作用(对吧?).
没有虚拟克隆方法,无法克隆多态对象.所以你可以:
最后一个是你用C++ 0x建议的std::unique_ptr,但在这种情况下,C++ 03 std::auto_ptr会为你提供完全相同的服务(即你不需要移动它,否则它们是相同的).
编辑:好的,嗯,还有一个方法:
printer自己成为实际实现的智能指针.比它的可复制和多态同时以一些复杂性为代价.| 归档时间: |
|
| 查看次数: |
3488 次 |
| 最近记录: |