Does it violate any OOP principal if a member function does not use any of class properties/member variables?
No.
OOP doesn't care if your member function uses, or doesn't use, class properties or member variables. OOP cares about polymorphism and not hard coding implementation. Static functions have their uses but a function shouldn't be static simply because it doesn't depend on object state. If that's your thinking fine, but don't blame it on OOP because that idea didn't come from OOP.
Is [it] bad design [to not] make use of member variables?
If you don't need to remember state from call to call there is no good reason to use state.
Which principle of Object oriented design [does] it violate?
None.
If a member function does not use the member variable then that member function should always be made static?
No. This thinking has the implication arrow going in the wrong direction.
Making the function static here is completely up to you. But it will make it more like a global if you do. Before going static consider hosting the function in a stateless class. It's more flexible.
I have here an OOP example of a member function that doesn't use class properties or member variables.
The member function (and it's stateless class):
#include <iostream>
class Strategy
{
public:
virtual int execute (int a, int b) = 0; // execute() is a so-called pure virtual
// function. As a consequence, Strategy
// is a so-called abstract class.
};
Three different implementations:
class ConcreteStrategyAdd:public Strategy
{
public:
int execute(int a, int b)
{
std::cout << "Called ConcreteStrategyAdd's execute()\n";
return a + b;
}
};
class ConcreteStrategySubstract:public Strategy
{
public:
int execute(int a, int b)
{
std::cout << "Called ConcreteStrategySubstract's execute()\n";
return a - b;
}
};
class ConcreteStrategyMultiply:public Strategy
{
public:
int execute(int a, int b)
{
std::cout << "Called ConcreteStrategyMultiply's execute()\n";
return a * b;
}
};
A place to store the choice of implementation:
class Context
{
private:
Strategy* pStrategy;
public:
Context (Strategy& strategy)
: pStrategy(&strategy)
{
}
void SetStrategy(Strategy& strategy)
{
pStrategy = &strategy;
}
int executeStrategy(int a, int b)
{
return pStrategy->execute(a,b);
}
};
An example of use
int main()
{
ConcreteStrategyAdd concreteStrategyAdd;
ConcreteStrategySubstract concreteStrategySubstract;
ConcreteStrategyMultiply concreteStrategyMultiply;
Context context(concreteStrategyAdd);
int resultA = context.executeStrategy(3,4);
context.SetStrategy(concreteStrategySubstract);
int resultB = context.executeStrategy(3,4);
context.SetStrategy(concreteStrategyMultiply);
int resultC = context.executeStrategy(3,4);
std::cout << "\nresultA: " << resultA
<< "\nresultB: " << resultB
<< "\nresultC: " << resultC
<< "\n";
}
Outputs:
Called ConcreteStrategyAdd's execute()
Called ConcreteStrategySubstract's execute()
Called ConcreteStrategyMultiply's execute()
resultA: 7
resultB: -1
resultC: 12
And all without execute()
caring about the state of any object. The Strategy
class is actually stateless. Only state is in Context
. Stateless objects are perfectly fine in OOP.
Found this code here.