【发布时间】:2011-05-24 06:44:29
【问题描述】:
我有一个类 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;
};
但是当printer 是一个多态基类时,这不再有效(切片)。
考虑到这一点,最好的方法是什么
- 我不想将指针传递给构造函数,并且
-
printer类不应需要虚拟的clone方法(= 需要依赖复制构造)。
我不想将指针传递给构造函数,因为 API 的其余部分使用的是真实对象,而不是指针,并且在这里将指针作为参数会令人困惑/不一致。
在 C++0x 下,我或许可以使用 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");
}
这是最好的选择吗?如果是这样,pre-0x 中最好的方法是什么?有没有办法摆脱构造函数中完全不必要的副本?不幸的是,移动临时的在这里不起作用(对吧?)。
【问题讨论】:
-
好吧,
unique_ptr在所有实际用途中都表现为指针,区别在于生命周期管理。 -
+1
Extra parens to prevent MVP.:D -
顺便说一句。该构造函数模板可能会干扰您的复制构造函数,至少我似乎记得 Visual Studio 在某些时候抱怨过它......
-
你能解释一下
Extra parens to prevent MVP.吗? -
@Mark MVP = most vexing parse