baseclass enforcing one of two methods

S

shaun roe

Sorry the subject line isnt more explanatory, difficult to be succinct:

I have a base class to a bunch of classes which fill a data structure
and return that data structure, in each case the 'filling' method can
have Either the signature of

bool fillData();

OR

bool fillData(int &i, list<string> & changeParams);

Is it possible to make a baseclass which will enforce that the derived
classes have one or other of these functions? so far my baseclass has

virtual bool fillData(){}
virtual bool fillData(int &i, list<string> & changeParams){}

i.e. a default 'do nothing' implementation for both, which doesnt
enforce anything.

cheers
shaun
 
O

Ondra Holub

shaun roe napsal:
Sorry the subject line isnt more explanatory, difficult to be succinct:

I have a base class to a bunch of classes which fill a data structure
and return that data structure, in each case the 'filling' method can
have Either the signature of

bool fillData();

OR

bool fillData(int &i, list<string> & changeParams);

Is it possible to make a baseclass which will enforce that the derived
classes have one or other of these functions? so far my baseclass has

virtual bool fillData(){}
virtual bool fillData(int &i, list<string> & changeParams){}

i.e. a default 'do nothing' implementation for both, which doesnt
enforce anything.

cheers
shaun

It is AFAIK not possible. You can use some workaround:
- write default implementation to throw and error (test for definition
will not be done during compilation, but you will be able to see it in
program)
- define both function as one function with default parameter values.
When you are using references, you can set default values to some
private static dummy variables and in the method you can easily check,
whether is it the default value. Then this method may be pure virtual
in base class
- You can define only one method again with one parameter which is
const reference to some class/struct instance which hold required
parameters
 
M

mlimber

shaun said:
Sorry the subject line isnt more explanatory, difficult to be succinct:

I have a base class to a bunch of classes which fill a data structure
and return that data structure, in each case the 'filling' method can
have Either the signature of

bool fillData();

OR

bool fillData(int &i, list<string> & changeParams);

Is it possible to make a baseclass which will enforce that the derived
classes have one or other of these functions? so far my baseclass has

virtual bool fillData(){}
virtual bool fillData(int &i, list<string> & changeParams){}

i.e. a default 'do nothing' implementation for both, which doesnt
enforce anything.

No, but you could make derviced classes support both by making them
pure virtual functions. See this FAQ:

http://www.parashift.com/c++-faq-lite/abcs.html#faq-22.4

If you made the base class have a default implementation as well:

class Base
{
virtual bool f() = 0 { return true; }
virtual bool f( int ) = 0 { return true; }
};

Then the Derived classes must override both, but they could call the
base implementation explicitly if they had nothing to add:

class Derived : public Base
{
virtual bool f() { /*Do something Derived specific */ return true; }
virtual bool f( int i ) { return Base::f( i ); }
};

BTW, if your derived classes don't support the full interface provided
by the base, then you don't have true polymorphism, which may indicate
a design flaw.

Cheers! --M
 
S

shaun roe

"mlimber said:
No, but you could make derviced classes support both by making them
pure virtual functions. See this FAQ:

http://www.parashift.com/c++-faq-lite/abcs.html#faq-22.4

If you made the base class have a default implementation as well:

class Base
{
virtual bool f() = 0 { return true; }
virtual bool f( int ) = 0 { return true; }
};

Then the Derived classes must override both, but they could call the
base implementation explicitly if they had nothing to add:

class Derived : public Base
{
virtual bool f() { /*Do something Derived specific */ return true; }
virtual bool f( int i ) { return Base::f( i ); }
};

BTW, if your derived classes don't support the full interface provided
by the base, then you don't have true polymorphism, which may indicate
a design flaw.

Cheers! --M

Thanks, this looks ok; although I agree I might discover that your last
comment is the most relevant...
 
G

Grizlyk

mlimber said:
class Base
{
need "public:" here
virtual bool f() = 0 { return true; }
"error: pure-specifier on function-definition"
In new versions of C++ you need define separate protected member:

protected:
inline bool implementation_f() { return true; }

and use "implementation_f" in derived if needed.
virtual bool f( int ) = 0 { return true; }
};
class Derived : public Base
{
virtual bool f() { /*Do something Derived specific */ return true; }
virtual bool f( int i ) { return Base::f( i ); }

And instead of explicit forwarding here, it is possible to use "using"
keyword, like this

class Derived : public Base
{
using Base::f;
bool f() { /*Do something Derived specific */ return true; }
};
 
S

shaun roe

"Grizlyk said:
need "public:" here

"error: pure-specifier on function-definition"
In new versions of C++ you need define separate protected member:

protected:
inline bool implementation_f() { return true; }

and use "implementation_f" in derived if needed.



And instead of explicit forwarding here, it is possible to use "using"
keyword, like this

class Derived : public Base
{
using Base::f;
bool f() { /*Do something Derived specific */ return true; }
};

Thanks; I quickly saw that my compiler (gcc 3.23) didn't like

virtual bool f() = 0 {return true;}

complaining that I was treating f() like a variable. Hopefully tour
approach will knock it on the head...

cheers
shaun
 
M

mlimber

Grizlyk said:
need "public:" here

Or "protected:". Mea culpa.
"error: pure-specifier on function-definition"
In new versions of C++ you need define separate protected member:

protected:
inline bool implementation_f() { return true; }

and use "implementation_f" in derived if needed.

Mea culpa again, but you don't need a separate function; you just can't
define the function at the point of definition on compliant compilers
(several, including a couple of mine, allow it as an extension,
however). This should work everywhere:

class Base
{
protected:
virtual bool f() = 0;
virtual bool f( int ) = 0;
};

bool Base::f() { return true; }
bool Base::f(int) { return false; }
And instead of explicit forwarding here, it is possible to use "using"
keyword, like this

class Derived : public Base
{
using Base::f;
bool f() { /*Do something Derived specific */ return true; }
};

No you can't because the function is a pure virtual and must be
explicitly overridden in the derived class.

Cheers! --M
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top