I have a class, and let's called it class myClass
class myClass{
// some math operations
myClass get_difference(myClass &b)
{
print_operation(*this, b);
do_something else
return...
}
myClass get_sum(myClass &b)
// pseudocode
void print_operation(const myClass *a, const myClass &b)
{
if function == get_sum
print a << "plus" << b;
if function == get_difference
print a << "minus" << b;
}
// overload cout as well
};
Suppose I called the following
myClass anObject(1,2);
myClass anotherObject(3,4);
anObject.get_sum(anotherObject);
anObject.get_difference(anotherObject);
get_sum / get_difference will call print_operation, but I want to be able to determine the caller so a different output format is used.
Naive approach: Use switch-case Add a new parameter called "id". Give each function (the caller) an id, and use switch-case statements in print_operation.
However, is there an alternative? A more elegant solution?
Thanks.
Have you considered adding a virtual const std::string& getFormatted() const
in the caller?
If the format will be a function of both arguments to your operator, you would have to create some kind of table of combinations to look up your format.
If the format is only a function of the length of the printing of each argument (much simpler), you could use virtual size_t getFormatLength() const
.
Note: print_operation() doesn't know anything about the caller, except that it has a getFormatted() function, yet the caller gets to format itself based on the value of op.
This is OOP/polymorphism at work.
As Andrew Marshall answered in his comment above, part of OOP/encapsulation is, you should not know anything about the implementation of the caller.
Polymorphism, done right, should try to encapsulate the implementation details away from the caller.
class myClass
{
public:
virtual std::string getFormatted( const std::string& op ) const = 0;
};
class A : public myClass
{
public:
virtual std::string getFormatted( const std::string& op ) const
{
// switch on the value of op or the length of op, etc...
return std::string( "this, formatted according to class A specs and op" );
}
};
class B : public myClass
{
public:
virtual std::string getFormatted( const std::string& op ) const
{
// switch on the value of op or the length of op, etc...
return std::string( "this, formatted according to class B specs and op" );
}
};
void print_operation(const myClass &a, const myClass &b )
{
std::string op;
if ( function == get_sum ) {
op = "plus";
} else if ( function == get_difference ) {
op = "minus";
}
std::cout << a.getFormatted( op ) << op << b.getFormatted( op );
}