0

Hi all,

My title might not describe this problem as well as it could, but I'm not sure what area this problem falls under.

I have a simple base class and derived class as follows:

class BaseClass
{
public:
    BaseClass()
    {
        parameterA_ = -0.0;
        parameterB_ = -0.0;
    }

    virtual ~BaseClass()
    {
    }

    void setParameterA( const double& parameterA )
    {
        parameterA_ = parameterA;
    };

    void setParameterB( const double& parameterB )
    {
        parameterB_ = parameterB;
    };

    void checkIfAllParametersSet()
    {
        if ( parameterA_ == -0.0 || parameterB_ == -0.0 )
        {
            isParametersSet = false;
        }
        else
        {
            isParametersSet = true;
        }
    };

    virutal void computeQuantity() =0;
protected:
    double parameterC_;
private:
    double parameterA_;
    double parameterB_;
    bool isParametersSet;
}

class DerivedClass
{
public:
    void computeQuantity()
    {
        if ( isParametersSet )
        {
            parameterC_ = parameterA_ * parameterB_;    
        }
    };
protected:
private:
}

So basically, though this might not be the most efficient way to program it, what I am trying to illustrate with this code is that in the derived class, an if-statement is used as check to ensure that the set functions have been executed to assign values to parameterA_ and parameterB_. In case either of these set functions, or both, have not been called, then the compute function should not execute instructions.

I am trying to set this code up for other developers to use, and what I want to do is hide the if-statement in the compute function in the derived class. Basically, the check to ensure whether all the necessary set functions have been called is something that I want to hide from the user and execute automatically. I can place this code in a function in the base class, but then I can't seem to figure out a way to call it automatically.

I can place the call to the check function in each of the set functions, and this way, only make the boolean true when all the set functions are called. The only thing is that this means that the number of calls to the check function grows with the number of set functions.

I was wondering if there is a way that I can execute this code automatically when the compute function is called, without actually placing the call to the check function explicitly in the compute function.

I thought I could do this by making the pure virtual compute function in the base function a virtual function with a call to the check function, however I can't add to this function by implementing it in the derived class I realise; I can only overwrite the contents of the virtual function.

I thought maybe I could use templates, and specifically template specialization, to achieve this, but I am not familiar with templates, so I'm not sure what the implementation would entail.

I hope it is clear what I am trying to achieve. I would appreciate any help at all. If anything is unclear, please let me know.

Thanks in advance,

Cheers,

Kartik

Edited by TheWolverine: n/a

2
Contributors
1
Reply
2
Views
6 Years
Discussion Span
Last Post by firstPerson
0

I think this is a good design for you :

#include <iostream>

using namespace std;

struct Base{
	int a,b;
	Base(int a = 0, int b = 0) : a(a), b(b) {}	

	virtual int calculate()const{
		if(!validatePreCondition()) return -1;
		int res = compute();
		if(!validatePostCondition()) return -1;
		return res;
	}

private:
	virtual int compute()const = 0;	

	virtual bool validatePreCondition()const{
		return true;
	}
	virtual bool validatePostCondition()const{
		return true;
	}
};

struct Derived : Base{
public:
	Derived(int a = 0, int b = 0)
		: Base(a,b){}
private:
	int compute()const{
		return a * b;
	}
	bool validatePreCondition()const{
		return a > 0 && b > 0;
	}
};
int main(){	
	Derived d(5,3);
	cout << d.calculate() << endl; //show 15
	
	Derived e(0,0);
	cout << e.calculate() << endl; //shows -1
}

If a user wants to derive form the Base class, then all he needs to do is define
the function calculate(), and he can add his own pre/post condition. This makes it
much more versatile. The user can create his own pre and post condition if he wishes,
or just create the compute function and use the default pre/post condition that always returns true.

I'm not sure if this is a known pattern or not, but I use it when I need to.

Edited by firstPerson: n/a

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.