Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return-type polymorphism for pass-by-value

I'm not sure if the question title is accurate... Let me start by explaining my original simple scenario, and then move on to explain what would I like to do, but can't.

Originally, I had something like:

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

So far so good (I think). However, there are now several derived operand types, e.g. class RegisterOperand : public Operand. I have new, dedicated genOperand functions that ideally would return instances of the derived types. But I can't do this:

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

and I can't do this:

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

static const OpGen generators[] = 
{
    ...
    genOperandC,
};

However, I know this would work if I were to return reference or pointer types, so the only option I currently have is something like:

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

which now requires explicit cleanup which wasn't necessary originally.

Any alternatives I haven't considered?

like image 690
Oliver Charlesworth Avatar asked Jun 21 '10 08:06

Oliver Charlesworth


1 Answers

You can wrap:

class Operand
{
public:

private:
  std::unique_ptr<OperandImpl> mImpl;
};

This is similar to a Strategy Pattern: the actual operand behavior is hidden, and accessible through a Non-Virtual Interface. The user get a copy of Operand, she does not need to know anything about its internal and can use it, and you are free to implement various derived behaviors.

like image 72
Matthieu M. Avatar answered Sep 23 '22 02:09

Matthieu M.