Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   baseclass enforcing one of two methods (http://www.velocityreviews.com/forums/t459894-baseclass-enforcing-one-of-two-methods.html)

shaun roe 01-18-2007 01:19 PM

baseclass enforcing one of two methods
 
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

Ondra Holub 01-18-2007 01:35 PM

Re: baseclass enforcing one of two methods
 

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


mlimber 01-18-2007 01:46 PM

Re: baseclass enforcing one of two methods
 
shaun roe wrote:
> 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-lit....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


shaun roe 01-18-2007 02:05 PM

Re: baseclass enforcing one of two methods
 
In article <1169127987.097205.112620@l53g2000cwa.googlegroups .com>,
"mlimber" <mlimber@gmail.com> wrote:

> shaun roe wrote:
> > 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-lit....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...

Grizlyk 01-19-2007 05:37 AM

Re: baseclass enforcing one of two methods
 
mlimber wrote:

> 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; }
};


shaun roe 01-19-2007 08:48 AM

Re: baseclass enforcing one of two methods
 
In article <1169185040.119426.74760@m58g2000cwm.googlegroups. com>,
"Grizlyk" <grizlyk1@yandex.ru> wrote:

> mlimber wrote:
>
> > 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; }
> };


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

mlimber 01-19-2007 02:03 PM

Re: baseclass enforcing one of two methods
 
Grizlyk wrote:
> mlimber wrote:
>
> > class Base
> > {

> need "public:" here


Or "protected:". Mea culpa.

> > 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.


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; }

> > 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; }
> };


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

Cheers! --M



All times are GMT. The time now is 09:48 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.