roang - 2 months ago 22

C++ Question

I was watching Google talk on polymorphism and clean code.

In that, the speaker was explaining how to create a clean code for an operation like 1+2*3

`class Node{`

virtual double evaluate() = 0;

};

class ValueNode :Node{

double value;

double evaluate(){

return value;

}

};

class OpNode :Node{

Node left;

Node right;

virtual double evaluate() = 0;

};

class AdditionNode : OpNode{

double evaluate(){

return left.evaluate() + right.evaluate();

}

};

class MultiplyNode : OpNode{

double evaluate(){

return left.evaluate() * right.evaluate();

}

};

I just copied the speaker's java code in c++. But in c++

`Node left;`

Node right;

will mean that left and right are objects of Node which is an abstract class and hence not allowed.

How do I fix this.

Answer

Polymorphism only works when you use pointers/references to objects. In Java, class objects are always allocated dynamically and referred to by pointer. So, in C++, the class declarations would need to look like this:

```
class Node {
public:
virtual double evaluate() = 0;
};
class ValueNode : public Node {
public:
double value;
double evaluate() {
return value;
}
};
class OpNode : public Node {
public:
Node *left;
Node *right;
};
class AdditionNode : public OpNode {
public:
double evaluate() {
return left->evaluate() + right->evaluate();
}
};
class MultiplyNode : public OpNode {
public:
double evaluate() {
return left->evaluate() * right->evaluate();
}
};
```

And then you can set up the example expression `1+(2*3)`

like this:

```
ValueNode value1;
value1.value = 1;
ValueNode value2;
value2.value = 2;
ValueNode value3;
value3.value = 3;
MultiplyNode multiply;
multiply.left = &value2;
multiply.right = &value3;
AdditionNode add;
add.left = &value1;
add.right = &multiply;
double result = add.evaluate();
```

When `add.evaluate()`

is called, it returns the sum of the values returned by calling `left->evaluate()`

and `right->evaluate()`

, where `left`

is pointing at `value1`

and `right`

is pointing at `multiply`

.

When `value1->evaluate()`

is called, it returns its `value`

field, which is `1`

.

When `multiply->evaluate()`

is called, it returns the product of the values returned by calling `left->evaluate()`

and `right->evaluate()`

, where `left`

is pointing at `value2`

and `right`

is pointing at `value3`

.

When `value2->evaluate()`

is called, it returns its `value`

field, which is `2`

.

When `value3->evaluate()`

is called, it returns its `value`

field, which is `3`

.

Thus, `add.evaluate()`

returns the sum of `1`

plus `2*3`

, which is `7`

.