Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > simulating "static pure virtual" methods

Reply
Thread Tools

simulating "static pure virtual" methods

 
 
cppaddict
Guest
Posts: n/a
 
      05-24-2004
Hi,

I know that it is illegal in C++ to have a static pure virtual method,
but it seems something like this would be useful when the following 2
conditions hold:

1. You know that every one of your Derived classes will need to
implement some method, but implement it differently, and that the base
class cannot implement it. This is where pure virtual comes in.

2. You know that for every one of your Derived classes, the method
never uses or alters member data. Thus it should be static.

To give a concrete example.

Say you have an abstract Document class, which has a method called
processDocument:

void processDocument() {
if (isApproved(_documentAuthor))
callSomeNonVirtualFunction();
else
callAnotherNonVirtualFunction();
}

Just to take an easy example, let's say that we know isApproved() is
some silly function of the author's name, which is passed in as an
arguement. Maybe for a derived KinkosDocument, isApproved() returns
true if the author's name begins with "A", and is otherwise false.
For some other derived class the rule would be different, but always a
function of the author's name itself.

So we have the following:

1. isApproved() should not be implemented in the base Document class.

2. isApproved() must be implemented in any derived concrete class.

3. isApproved() must be a simple function of a string.

What is the right design for a situation like this?

Thanks,
cpp

 
Reply With Quote
 
 
 
 
Sharad Kala
Guest
Posts: n/a
 
      05-24-2004

"cppaddict" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Hi,
>
> I know that it is illegal in C++ to have a static pure virtual method,
> but it seems something like this would be useful when the following 2
> conditions hold:
>

Perhaps you need something like this -

struct A{
virtual void foo() =0;
};

struct B : A{
void foo(){
staticB();
}
static void staticB(){}
};

struct C : A{
void foo(){
staticC();
}

static void staticC(){}
};

int main()
{
}

-Sharad


 
Reply With Quote
 
 
 
 
Karl Heinz Buchegger
Guest
Posts: n/a
 
      05-24-2004
cppaddict wrote:
>
> Hi,
>
> I know that it is illegal in C++ to have a static pure virtual method,
> but it seems something like this would be useful when the following 2
> conditions hold:
>
> 1. You know that every one of your Derived classes will need to
> implement some method, but implement it differently, and that the base
> class cannot implement it. This is where pure virtual comes in.
>
> 2. You know that for every one of your Derived classes, the method
> never uses or alters member data. Thus it should be static.
>
> To give a concrete example.
>
> Say you have an abstract Document class, which has a method called
> processDocument:
>
> void processDocument() {
> if (isApproved(_documentAuthor))
> callSomeNonVirtualFunction();
> else
> callAnotherNonVirtualFunction();
> }
>
> Just to take an easy example, let's say that we know isApproved() is
> some silly function of the author's name, which is passed in as an
> arguement. Maybe for a derived KinkosDocument, isApproved() returns
> true if the author's name begins with "A", and is otherwise false.
> For some other derived class the rule would be different, but always a
> function of the author's name itself.


plus - and this is important - the type of Document which should
check the name. So in the above you simply cannot have a call
to isApproved only. It needs to be some class member. But then
you need an object of that class to determine the dynamic
type of the Derived class and hence isApproved can be
a normal virtual member function of that class.
There is nothing a static method can do better or worse
in this case. You still need an object to call the method
to identify the context in which the call should be made.

Static functions are usefull if you don't want to specify
any context but use the class as a sort of 'namespace', to avoid
a free standing function. In your example the function cannot
be freestanding, thus static isn't of any use to this problem.


--
Karl Heinz Buchegger
http://www.velocityreviews.com/forums/(E-Mail Removed)
 
Reply With Quote
 
Jeff Schwab
Guest
Posts: n/a
 
      05-24-2004
cppaddict wrote:
> Hi,
>
> I know that it is illegal in C++ to have a static pure virtual method,
> but it seems something like this would be useful when the following 2
> conditions hold:
>
> 1. You know that every one of your Derived classes will need to
> implement some method, but implement it differently, and that the base
> class cannot implement it. This is where pure virtual comes in.
>
> 2. You know that for every one of your Derived classes, the method
> never uses or alters member data. Thus it should be static.
>
> To give a concrete example.
>
> Say you have an abstract Document class, which has a method called
> processDocument:
>
> void processDocument() {
> if (isApproved(_documentAuthor))
> callSomeNonVirtualFunction();
> else
> callAnotherNonVirtualFunction();
> }
>
> Just to take an easy example, let's say that we know isApproved() is
> some silly function of the author's name, which is passed in as an
> arguement. Maybe for a derived KinkosDocument, isApproved() returns
> true if the author's name begins with "A", and is otherwise false.
> For some other derived class the rule would be different, but always a
> function of the author's name itself.
>
> So we have the following:
>
> 1. isApproved() should not be implemented in the base Document class.
>
> 2. isApproved() must be implemented in any derived concrete class.
>
> 3. isApproved() must be a simple function of a string.
>
> What is the right design for a situation like this?


There's no need for the base class to declare the method. The point of
virtual methods is to allow subclass-specific behavior through pointers
(or references) to objects of a base type. You can't have a pointer to
an entire class, so there's no point in having a static virtual method.

If client code expects some feature of a class, and that feature (e.g. a
static method with a particular name) is missing, you will get a
compile-time error.

If you want to ensure a priori that each of a group of types can be used
in particular ways, you can write a "constraints" class to express the
requirements. You do have to instantiate the class for each type you
want to check explicitly. If you find this approach useful, check out
the Boost Concept Checking library.

struct A
{
// Each subclass should have a default constructor, and a static
// method called "foo" that can be called with no arg's.
//
// Instantiate A::Check_constraints for each type derived from A
// to check these requirements.

template< typename T >
struct Check_constraints
{
static void check_for_default_constructor ( )
{
T t = T( );
}

static void check_for_static_method_foo( )
{
T::foo( );
}
};
};

struct B: A
{
static void foo( ) { }
B ( ) { }
};

struct C: A
{
C ( ) { }
};

/* Explicit instantiations verify that B and C meet A's requirements.
*/
template class A::Check_constraints< B >;
template class A::Check_constraints< C >;
 
Reply With Quote
 
jeffc
Guest
Posts: n/a
 
      05-24-2004

"cppaddict" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Hi,
>
> I know that it is illegal in C++ to have a static pure virtual method,
> but it seems something like this would be useful when the following 2
> conditions hold:
>
> 1. You know that every one of your Derived classes will need to
> implement some method, but implement it differently, and that the base
> class cannot implement it. This is where pure virtual comes in.
>
> 2. You know that for every one of your Derived classes, the method
> never uses or alters member data. Thus it should be static.


Why should it be static just because of that? If it's static, it can't be
virtual. Virtual is what allows overriding.


 
Reply With Quote
 
Andy Venikov
Guest
Posts: n/a
 
      05-24-2004
cppaddict <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>. ..
> Hi,
>
> I know that it is illegal in C++ to have a static pure virtual method,
> but it seems something like this would be useful when the following 2
> conditions hold:
>
> 1. You know that every one of your Derived classes will need to
> implement some method, but implement it differently, and that the base
> class cannot implement it. This is where pure virtual comes in.
>
> 2. You know that for every one of your Derived classes, the method
> never uses or alters member data. Thus it should be static.
>
> To give a concrete example.
>
> Say you have an abstract Document class, which has a method called
> processDocument:
>
> void processDocument() {
> if (isApproved(_documentAuthor))
> callSomeNonVirtualFunction();
> else
> callAnotherNonVirtualFunction();
> }
>
> Just to take an easy example, let's say that we know isApproved() is
> some silly function of the author's name, which is passed in as an
> arguement. Maybe for a derived KinkosDocument, isApproved() returns
> true if the author's name begins with "A", and is otherwise false.
> For some other derived class the rule would be different, but always a
> function of the author's name itself.
>
> So we have the following:
>
> 1. isApproved() should not be implemented in the base Document class.
>
> 2. isApproved() must be implemented in any derived concrete class.
>
> 3. isApproved() must be a simple function of a string.
>
> What is the right design for a situation like this?
>
> Thanks,
> cpp


Static functions can't be virtual for a reason. You use them
when you want to execute something class-specific without any
context, meaning without an object of that class. Virtual functions
make no sense without objects. In other words, to call a virtual
function, you need an object. But if you have an object, you don't
need the function to be static.

If what you want is for for each class to have it's own
implementation of isApproved, but be called not through the object
invocation, but through a class invocation, then you can achieve that by
just overloading the isApproved. The derived class's isApproved will
hide the base class's isApproved when you do this: Derived::isApproved.
The problem here is now you'll have to duplicate processDocument() in
each derived class, because parent's processDocument will only call
parent's isApproved().

If you make isApproved a public function, then you can use
a template function like this:

template <class T> void processDocument(documnetAuthor)
{
if (T::isApproved(documentAuthor))
T::SomeNonVirtualF;
else
T::SomeOtherNonVirtualF;
}

and call it like this

processDocument<DerivedDoc>(documentAuthor);

Andy.
 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      05-24-2004
Andy Venikov wrote:
> cppaddict <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>. ..
> > [...]

>
> Static functions can't be virtual for a reason. You use them
> when you want to execute something class-specific without any
> context, meaning without an object of that class. Virtual functions
> make no sense without objects. In other words, to call a virtual
> function, you need an object. But if you have an object, you don't
> need the function to be static.
> [...]


Andy, take a look at the recent thread in comp.std.c++ about static
virtual functions (titled "static member functions and 'virtual'",
started by David Whipp) and the explanation why they can be of use,
perhaps you will not be as rigid after that.

Victor
 
Reply With Quote
 
cppaddict
Guest
Posts: n/a
 
      05-24-2004
Karl,

Thanks for your reply. I've got a couple more questions though...

>Static functions are usefull if you don't want to specify
>any context but use the class as a sort of 'namespace', to avoid
>a free standing function. In your example the function cannot
>be freestanding, thus static isn't of any use to this problem.


I think my point is that my the function isApproved() could just as
well be freestanding. It just processes a string passed to it and
returns true/false. The only reason that I don't want it to be
freestanding is that the only place I'm using it is in this class, and
I want to make that connection clear by having it be a member
function. Thus your description of static functions only being useful
as a sort of 'namespace' applies perfectly here. It's just that I
also want to say syntactically: "This function will be implemented by
all derived classes."

To give you an idea of my priorities, right now my solution is simply
to have isApproved be a virtual function, and ignore the fact that it
doesn't really require any context. Indeed, to give it context, I
could have it operate on _documentAuthor directly instead of passing
that in as an argument. Then I would no longer feel that it "should"
be static. Perhaps that is the real issue here....

Thanks for any further thoughts,
cpp

 
Reply With Quote
 
Dave Townsend
Guest
Posts: n/a
 
      05-24-2004
I think in this example you'd be better off using a "strategy" design
pattern
or something else like policy classes.

In the strategy pattern approach, you will have a data member which
provides the IsApproved() method. You can construct the class by
passing such an approval object as a parameter to the constructor.
In this way, the workings of the class can be left alone, the approval
object provides the variations in the approval. This is good if all that
is varying is the approval behavior, not the document behavior.


for example:

class Document
{
public:
Document( Approver* approver );

};

class Approver
{
public:
virtual bool isApproved()=0;
};

class KinkoApprover
{
public:
virtual bool isApproved () { ....do approval ...}
};
class OfficeDepotApprover
{
public:
virtual bool isApproved () { ....do approval ...}
};

Document* kinkoDoc = new Document( new KinkoApprover() );
Document* officeDepotDoc = new Document( new OfficeDepotApprover() );


dave


"cppaddict" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Hi,
>
> I know that it is illegal in C++ to have a static pure virtual method,
> but it seems something like this would be useful when the following 2
> conditions hold:
>
> 1. You know that every one of your Derived classes will need to
> implement some method, but implement it differently, and that the base
> class cannot implement it. This is where pure virtual comes in.
>
> 2. You know that for every one of your Derived classes, the method
> never uses or alters member data. Thus it should be static.
>
> To give a concrete example.
>
> Say you have an abstract Document class, which has a method called
> processDocument:
>
> void processDocument() {
> if (isApproved(_documentAuthor))
> callSomeNonVirtualFunction();
> else
> callAnotherNonVirtualFunction();
> }
>
> Just to take an easy example, let's say that we know isApproved() is
> some silly function of the author's name, which is passed in as an
> arguement. Maybe for a derived KinkosDocument, isApproved() returns
> true if the author's name begins with "A", and is otherwise false.
> For some other derived class the rule would be different, but always a
> function of the author's name itself.
>
> So we have the following:
>
> 1. isApproved() should not be implemented in the base Document class.
>
> 2. isApproved() must be implemented in any derived concrete class.
>
> 3. isApproved() must be a simple function of a string.
>
> What is the right design for a situation like this?
>
> Thanks,
> cpp
>



 
Reply With Quote
 
cppaddict
Guest
Posts: n/a
 
      05-24-2004

>In the strategy pattern approach, you will have a data member which
>provides the IsApproved() method. You can construct the class by
>passing such an approval object as a parameter to the constructor.
>In this way, the workings of the class can be left alone, the approval
>object provides the variations in the approval. This is good if all that
>is varying is the approval behavior, not the document behavior.


Dave,

Thanks for that. That would work here and seems appropriate. But
how, in general, does one decide when a Strategy Pattern is
appropriate and when a virtual function is appropriate?

Both methods seem to allow you to separate out implementation from
context.

Thanks again,
cpp
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Is there a way to find the class methods of a class, just like'methods' finds the instance methods? Kenneth McDonald Ruby 5 09-26-2008 03:09 PM
Pure space directly inside div ignored, but pure space directlyinside span honored liketofindoutwhy@gmail.com HTML 4 03-29-2008 06:06 PM
Simulating polymorphism without the overhead of virtual methods? jpr C++ 2 03-25-2006 11:52 PM
embedding python: simulating sequence get item / set item methods Johannes Zellner Python 1 01-17-2006 01:09 AM
Pure functions still pure after definition Todd Aspeotis C++ 3 05-30-2005 03:53 AM



Advertisments