我不确定问题标题是否准确......让我先解释一下我原来的简单场景,然后继续解释我想做什么,但不能.
最初,我有类似的东西:
class Operand;
Operand genOperandA() { ...; return Operand(); }
Operand genOperandB() { ...; return Operand(); }
... // more operand-generation functions
typedef Operand (*OpGen)();
// Table of function pointers
static const OpGen generators[] =
{
genOperandA,
genOperandB,
...
};
// Function to do some operation on the operand
void operate(Operand& op);
...
// Example call
operate(generators[1]());
Run Code Online (Sandbox Code Playgroud)
到目前为止这么好(我想).但是,现在有几种派生的操作数类型,例如class RegisterOperand : public Operand.我有新的专用genOperand函数,理想情况下会返回派生类型的实例.但我不能这样做:
Operand genOperandC() { ...; return RegisterOperand(); }
Run Code Online (Sandbox Code Playgroud)
我不能这样做:
RegisterOperand genOperandC() { ...; return RegisterOperand(); }
static const OpGen generators[] =
{
...
genOperandC,
};
Run Code Online (Sandbox Code Playgroud)
但是,我知道如果我要返回引用或指针类型,这将有效,所以我目前唯一的选择是:
Operand *genOperandC() { ...; return new RegisterOperand(); }
Run Code Online (Sandbox Code Playgroud)
现在需要明确的清理,这是原本不必要的.
我还没考虑过任何替代方案?
你可以包装:
class Operand
{
public:
private:
std::unique_ptr<OperandImpl> mImpl;
};
Run Code Online (Sandbox Code Playgroud)
这与策略模式类似:实际的操作数行为是隐藏的,可通过非虚拟接口访问.用户获得一份副本Operand,她不需要知道任何有关其内部的内容并且可以使用它,并且您可以自由地实现各种派生行为.
可能还有其他设计不需要您使用指针,但如果您需要或想要这样做,这可能会让您感兴趣。
如果返回指针是一个问题(因为需要“清理”东西),那么您绝对应该考虑使用智能指针作为返回类型。
这是带有智能指针的工厂方法的示例:
boost::shared_ptr<Operand> genOperandC()
{
return boost::shared_ptr<Operand>(new RegisterOperand());
}
Run Code Online (Sandbox Code Playgroud)
这样,您就不必手动调用:它将在需要时由 的析构函数为您delete完成。boost::shared_ptr<Operand>
如果之后您需要转换结果指针,boost也提供转换函数:
boost::shared_ptr<Operand> op = genOperandC();
boost::shared_ptr<RegisterOperand> rop =
boost::dynamic_pointer_cast<RegisterOperand>(op);
Run Code Online (Sandbox Code Playgroud)