代码之家  ›  专栏  ›  技术社区  ›  Oliver Charlesworth

传递值的返回类型多态性

  •  11
  • Oliver Charlesworth  · 技术社区  · 14 年前

    最初,我有这样的想法:

    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]());
    

    到目前为止还不错(我认为)。但是,现在有几种派生操作数类型,例如。 class RegisterOperand : public Operand . 我有新的,专注的 genOperand 理想情况下会返回派生类型实例的函数。但我不能这么做:

    Operand genOperandC() { ...; return RegisterOperand(); }
    

    我不能这么做:

    RegisterOperand genOperandC() { ...; return RegisterOperand(); }
    
    static const OpGen generators[] = 
    {
        ...
        genOperandC,
    };
    

    但是,我知道如果要返回引用或指针类型,这将起作用,因此我当前唯一的选择是:

    Operand *genOperandC() { ...; return new RegisterOperand(); }
    

    有没有我没考虑过的替代方案?

    4 回复  |  直到 14 年前
        1
  •  4
  •   ereOn    14 年前

    可能还有其他设计不需要您使用指针,但是如果您需要或想要这样做,这可能会引起您的兴趣。


    如果返回一个指针是一个问题(因为需要“清理”东西),您肯定应该考虑使用智能指针作为返回类型。

    以下是使用智能指针的工厂方法的示例:

    boost::shared_ptr<Operand> genOperandC()
    {
      return boost::shared_ptr<Operand>(new RegisterOperand());
    }
    

    这样,你就不用打电话了 delete 手动:将由的析构函数完成 boost::shared_ptr<Operand>

    如果之后需要转换结果指针, boost 还提供铸造功能:

    boost::shared_ptr<Operand> op = genOperandC();
    
    boost::shared_ptr<RegisterOperand> rop =
      boost::dynamic_pointer_cast<RegisterOperand>(op);
    
        2
  •  7
  •   Matthieu M.    14 年前

    您可以包装:

    class Operand
    {
    public:
    
    private:
      std::unique_ptr<OperandImpl> mImpl;
    };
    

    这类似于策略模式:实际操作数行为是隐藏的,可以通过非虚拟接口访问。用户获取 Operand

        3
  •  0
  •   Community Alok Save    7 年前

    我知道这个问题前一段时间有人问过,但最近我自己也遇到了这个问题,我想出了一个不同的解决方案,我认为在这里可以有所帮助。

    class PolymorphicType {
    public: 
         /* 
             Class interface ...
         */
         PolymorphicType() { it = nullptr; }
         virtual ~PolymorphicType() { if(it != nullptr) delete it; }         
    
         PolymorphicType& operator=(const PolymorphicType& org) {
              //Clone the derived type and store it
              if(org.it != nullptr)
                  it = org.it->clone();
         }
    private:
         Base* it;
    };
    

    每个派生类现在都必须实现它自己的克隆方法,您就可以开始了! 为了以防万一,这里有一篇很好的帖子解释了派生类型的克隆是如何工作的: Copying derived entities using only base class pointers, (without exhaustive testing!) - C++

    希望这能帮到别人!