Why static pure virtual function is not possible?
Hello,
I don't know why static pure virtual methods are not implemented in C++?
And yet I need this functionality...
I would to have code like:
class Telegram
{
static virtual int getType() = 0;
};
class LoginTelegram : public Telegram
{
static virtual int getType() {return 0;}
};
class LocationTelegram : public Telegram
{
static virtual int getType() {return 1;}
};
int main()
{
Telegram *telegram;
telegram = new TelegramLogin;
cout << "LoginTelegramType: " << LoginTelegram::getType() << endl;
cout << "LocationTelegramType: " << LocationTelegram::getType() << endl;
cout << "This TelegramType: " << telegram->getType() << endl;
return 0;
}
[879 byte] By [
dlaugt] at [2007-11-18 17:43:20]

# 1 Re: Why static pure virtual function is not possible?
Because the 'static' modifier would make the pure virtual function accessible from outside...since you can access static members of a class without needing an actual instance...
# 2 Re: Why static pure virtual function is not possible?
Pure virtual functions mean "You cannot create an object of this type".
Static functions mean "You can call this function without an object".
So pure virtual static functions are indeed in contradiction with themselves.
For your example I do not see a good reason, why the function should be static.
# 3 Re: Why static pure virtual function is not possible?
Because the 'static' modifier would make the pure virtual function accessible from outside...since you can access static members of a class without needing an actual instance... And where is the problem?
Pure virtual functions mean "You cannot create an object of this type". Static functions mean "You can call this function without an object". So pure virtual static functions are indeed in contradiction with themselves. Yes... if you explain "static pure virtual" by two definitions separately. But you can say that the mix "static pure virtual" has the definition: "Must be implemented by inherited classes and implemented function in the HERITED CLASSES will be accessible with an instance or without an instance".
For your example I do not see a good reason, why the function should be static. The main of my example expresses the need. This need doesn't shock me...
# 4 Re: Why static pure virtual function is not possible?
My example can be writed in C++ like:
class Telegram
{
virtual int getType() = 0;
};
class LoginTelegram : public Telegram
{
virtual int getType() {staticGetType();}
static int staticGetType() {return 0;}
};
class LocationTelegram : public Telegram
{
virtual int getType() {staticGetType();}
static int staticGetType() {return 1;}
};
int main()
{
Telegram *telegram;
telegram = new TelegramLogin;
cout << "LoginTelegramType: " << LoginTelegram::staticGetType() << endl;
cout << "LocationTelegramType: " << LocationTelegram::staticGetType() << endl;
cout << "This TelegramType: " << telegram->getType() << endl;
return 0;
}
But it's not very nice. You have two functions which make same things... And theses functions can't have the same name...
# 5 Re: Why static pure virtual function is not possible?
Why does your function need to be PURE virtual? You could implement the function in a what that the base Telegram class returns an INVALID type...
# 6 Re: Why static pure virtual function is not possible?
The "problems" you've pointed at is with virtual functions in general, not only pure ones.
In order to determine the right virtual function to process,
the compiler generate a virtual table of virtual function pointers
for each class.
Each object (having virtual function/s) has an inner pointer to
his class's virtual table.
Without a "live" object, you have no way to access any
virtual function.
static function members don't need an object to be called,
therefore dynamic link of virtual function cannot be accomplished.
most of times, static functions members are interface
for static data members.
since you return a constant value in your functions,
using no static data member, you can drop the static modifier
and leave it virtual.
Guy
Guysl at 2007-11-9 0:35:57 >

# 7 Re: Why static pure virtual function is not possible?
Originally posted by dlaugt
And where is the problem?
Well...there is no problem at the end. It is a matter of viewing at things...
No one said that everything in the current specification is good or bad... :cool:
# 8 Re: Why static pure virtual function is not possible?
Consider the following (illegal) code:
class illegal
{
public:
static virtual void svfunc() = 0;
virtual void vfunc() = 0;
};
class bad : public illegal
{
public:
static virtual void svfunc();
virtual void vfunc();
};
class cantbedone : public illegal
{
public:
static virtual void svfunc();
virtual void vfunc();
};
int main()
{
illegal* ill1 = new bad;
illegal* ill2 = new cantbedone;
// The compiler can sort these out because at the time the
// object is created, it can do whatever is necessary to ensure
// that the virtual redirection works correctly.
ill1->vfunc();
ill2->vfunc();
// how is it supposed to know which derived class version
// should be called here without specifying it
// (and so defeat the point of having the function virtual)?
illegal::svfunc();
}
# 9 Re: Why static pure virtual function is not possible?
Why does your function need to be PURE virtual? You could implement the function in a what that the base Telegram class returns an INVALID type... If the base Telegram class returns an INVALID type that means that this function must be PURE. The function getType() has no sense for the base Telegram class. This function must be implemented on each inherited class and it's the role of a pure virtual function...
since you return a constant value in your functions, using no static data member, you can drop the static modifier and leave it virtual. No because it's not optimized. My function getType() is not dependent of an instance state. It's dependent of the class. This can be the role of static...
I would to have code like:
void testFunction(Telegram *telegram)
{
if (telegram->getType() == LoginTelegram::getType())
cout << "This is a login telegram" << endl;
else if (telegram->getType() == LocationTelegram::getType())
cout << "This is a location telegram" << endl;
}I don't want to write:
void testFunction(Telegram *telegram)
{
LoginTelegram loginTelegram;
LocationTelegram locationTelegram;
if (telegram->getType() == loginTelegram.getType())
cout << "This is a login telegram" << endl;
else if (telegram->getType() == locationTelegram.getType())
cout << "This is a location telegram" << endl;
}Because in this function I create two instances for nothing. It's consume time, memory. We have more line codes. And here, I have only two types of telegram, but if I have 50 types of telegrams... :)
Well...there is no problem at the end. It is a matter of viewing at things... No one said that everything in the current specification is good or bad... You are right... The problem is my function is valid for static usage but also for virtual usage. One solution is to create two functions like I has presented in my last answer.
// how is it supposed to know which derived class
// should be called here without specifying it version
// (and so defeat the point of having the function virtual)?
illegal::svfunc();
This line can be refused by the compiler because it's pure virtual...
# 10 Re: Why static pure virtual function is not possible?
Why can't you do this?#include <iostream>
class Telegram
{
public:
enum TelegramType {LOGIN, LOCATION};
virtual TelegramType getType() = 0;
};
class LoginTelegram : public Telegram
{
public:
virtual TelegramType getType()
{
return LOGIN;
}
};
class LocationTelegram : public Telegram
{
public:
virtual TelegramType getType()
{
return LOCATION;
}
};
int main()
{
Telegram* telegram = new LocationTelegram;
Telegram::TelegramType Type = telegram->getType();
if(Type == Telegram::LOGIN)
{
std::cout << "It's a login-telegram" << std::endl;
}
else if(Type == Telegram::LOCATION)
{
std::cout << "It's a location-telegram" << std::endl;
}
system("pause");
return 0;
}
# 11 Re: Why static pure virtual function is not possible?
Yes it's a good solution. But you add a dependance Telegram class to each derived class. Because in Telegram you must enumerate each type of derived classes.
One other solution is:
if (dynamic_cast<LoginTelegram*>(telegram))
cout << "This is a login telegram" << endl;
else if (dynamic_cast<LocationTelegram*>(telegram))
cout << "This is a location telegram" << endl;
We arrive to the limit of the problem. We found good solutions... But now if we consider that the static function getType() updates static data. We must return to the solution that we must implement two functions: one for static and one for virtual. Unfortunaly, for me, we can have a function that can be valid for static usage and virtual usage. "static" and "virtual" are not incompatible.
# 12 Re: Why static pure virtual function is not possible?
Originally posted by dlaugt
Yes it's a good solution. But you add a dependance Telegram class to each derived class. Because in Telegram you must enumerate each type of derived classes.Well... Seeing as though you will need to keep track of which telegram-types return which value either way, I find it preferable to keep the valid types as an enum in the base class, as opposed to going through each of your derived classes to check which return values are free each time you want to add another derived class. (Which you would have to do in your "static virtual" approach.)
EDIT: Corrected a misplaced word
# 13 Re: Why static pure virtual function is not possible?
You are right, your solution is better because it's describe exactly my need. Each telegram has a code being coded by an integer.
And I need functions in two case:
- I have a pointer on a Telegram class, I would like to use ptr->getType() to obtain the code of this telegram
- I would like to know the code of a specific telegram without to create an instance (Telegram::LOGIN or Telegram::LOCATION).
# 14 Re: Why static pure virtual function is not possible?
Oups where is my integer code?
We can write:
#include <iostream>
class Telegram
{
public:
static const int LOGIN = 0;
static const int LOCATION = 1;
virtual TelegramType getType() = 0;
};
class LoginTelegram : public Telegram
{
public:
virtual int getType()
{
return LOGIN;
}
};
class LocationTelegram : public Telegram
{
public:
virtual int getType()
{
return LOCATION;
}
};
int main()
{
Telegram* telegram = new LocationTelegram;
int Type = telegram->getType();
if(Type == Telegram::LOGIN)
{
std::cout << "It's a login-telegram" << std::endl;
}
else if(Type == Telegram::LOCATION)
{
std::cout << "It's a location-telegram" << std::endl;
}
system("pause");
return 0;
}
# 15 Re: Why static pure virtual function is not possible?
Well that does the same thing, except there's more typing.
If you need to specify the integer value of an enum member, you can write:enum TelegramType {LOGIN = 0, LOCATION = 1};
# 16 Re: Why static pure virtual function is not possible?
Please check the next code, I hope I get what you want :)
only a single function getType for the public interface
that can handle both object dependent and class dependant.
I know its not so elegant, but I think it works:
#include <iostream.h>
class Telegram
{
public:
int getType(){return getRealType();}
protected:
virtual int getRealType()=0;
};
class LoginTelegram : public Telegram
{
public:
static int getType() { return 0;}
protected:
virtual int getRealType() { return 0;}
};
class LocationTelegram : public Telegram
{
public:
static int getType() {return 1;}
protected:
virtual int getRealType() { return 1;}
};
int main()
{
Telegram *telegram = new LoginTelegram;
Telegram *telegram2= new LocationTelegram;
cout << "LoginTelegramType static output: " << LoginTelegram::getType() << endl;
cout << "LocationTelegramType static output: " << LocationTelegram::getType() << endl;
cout << "TelegramType of telegram: " << telegram->getType() << endl;
cout << "TelegramType of telegram2: " <<telegram2->getType() << endl;
return 0;
}
Guysl at 2007-11-9 0:46:10 >

# 17 Re: Why static pure virtual function is not possible?
I also think it is something related to "this " pointer.
# 18 Re: Why static pure virtual function is not possible?
Yes it's a good solution. It's exactly what I want: an unique function getType() for the public interface that can handle both object dependent and class dependant.
To be perfect, the virtual function in the derived classes can call the static function like:
#include <iostream.h>
class Telegram
{
public:
int getType(){return getRealType();}
protected:
virtual int getRealType()=0;
};
class LoginTelegram : public Telegram
{
public:
static int getType() { return 0;}
protected:
virtual int getRealType() { return getType();}
};
class LocationTelegram : public Telegram
{
public:
static int getType() {return 1;}
protected:
virtual int getRealType() { return getType();}
};
int main()
{
Telegram *telegram = new LoginTelegram;
Telegram *telegram2= new LocationTelegram;
cout << "LoginTelegramType static output: " << LoginTelegram::getType() << endl;
cout << "LocationTelegramType static output: " << LocationTelegram::getType() << endl;
cout << "TelegramType of telegram: " << telegram->getType() << endl;
cout << "TelegramType of telegram2: " <<telegram2->getType() << endl;
return 0;
} It's what I wanted at the beginning, a pure virtual function that is static. In C++, it's not possible. So it's resolved by: a function in the base class that calls a virtual function that calls a static function.
I make my Oriented Design of theses telegrams with UML without thinking langage or C++. For me, it was natural to have a static method in a class that is required to be defined in derived classes. During my implementation, I was surprised that is not possible. Once again, it's natural, effective and clean. All solutions found are great but are not perfect (several functions, only virtual so time consuming, group all types in the base class, ...). But it's normal C++ is like that.
Some persons told me that it can't be different, compilers works with v-table and ..... things too much complicate for me. Maybe there are right... Or maybe the specification forget this case and so compilers were implemented according to this limitation...
Thanks for all yours answers. I don't know yet which solution I will choose for my telegrams. But it will be one of yours.
Thanks.
# 19 Re: Why static pure virtual function is not possible?
Originally posted by Guysl
Please check the next code, I hope I get what you want :)
only a single function getType for the public interface
that can handle both object dependent and class dependant.
I know its not so elegant, but I think it works:Scott Meyer writes in his classic Effective C++: "Item 37: Never redefine an inherited non-virtual function." And there are good reasons for that, which are explained nicely in the book.
A static function allows you to call the function without having an object of the class (but you do need to know the class you are calling it for, not just the base class).
A virtual function allows you to call the function by having a pointer to the base class (thus having an object, but not knowing the exact class you are calling it for, just the base class).
If you need or want both, there is still no good reason why both should have the same name.
# 20 Re: Why static pure virtual function is not possible?
If you need or want both, there is still no good reason why both should have the same name. My reason is they make the same things.
# 21 Re: Why static pure virtual function is not possible?
hey treuss,
if we allowed to use weapons as Scott Meyers's EC++,
then please wait a minute... ok, Item 37, page 170, hmmm...
;)
Indeed, every word you've said is acceptable, except:
I do not redefine any inherited nonvirtual function...
The fact is, I do exactly as master Meyers suggest:
I redifine only virtual functions, and
I redifine static functions that are nor non-virtual neither virtual,
but ... static functions...
The problem Mr. Meyers pointed at, is irrelevant with
redefining static functions in our case since:
a.) we use them explicitly with class name,
using static bounding -
and not with a pointer that is hard to be tracked
( className::staticFunction(); )
b.) static functions have no privileges of beeing virtual,
therefore there is no design consideration between
non virtual / virtual, surprisingly
thats what dlaugt wanted to achieve in that
specific case.
Guy
Guysl at 2007-11-9 0:51:17 >

# 22 Re: Why static pure virtual function is not possible?
Hi..
I think if one goes by what u have for the definition for a SPVM
then ur question is indeed right.
i mean it may not be often used. but nevertheless i don't see anything that goes wrong if we implement what u r saying.
but that will have just one problem.
as of now..we can omit the definition of the inherited pure virtual methods in the inheriting class.
this way this class tooo will become an abstract class.
right?
this is useful when we are deriving from some abstract class but have not yet reached that point where we will be able to define our req.
now if we do what u r saying then any immediately class will be forced to define the inherited SPVM.
so that flexibility is lost.
but ur query too is valid upto a point...in fact a great deal more.
just one thing more.
static methods r supposed to be called without a class instance.
suppose this static methos call results in a call to this Pure Virtul method.
then?
the virtual table of the base class (this class only) will not have an entry for this pure virtual method...the rule says so.
and remember virtual methods r resolved at runtime...if a pointer is used
and so it wont always be possible to catch such errors at complie time...this means that the program is prone to crash.
maybe that's why u CANNOT have a SPVM.
well...it was just an effort from my side.
hope it helps you.
if there is nething wrong in my answer plz. tell me.
Bye,
King.
King at 2007-11-9 0:52:14 >

# 23 Re: Why static pure virtual function is not possible?
Originally posted by Guysl
hey treuss,
if we allowed to use weapons as Scott Meyers's EC++,
then please wait a minute... ok, Item 37, page 170, hmmm...
;)I don't have the book here at the moment, so I'll probably loose. But I try anyways ;)
Indeed, every word you've said is acceptable, except:
I do not redefine any inherited nonvirtual function...Well, you do! Your tricky implementation (non-virtual function calls pure virtual function) does not eliminate the fact that your interface violates exactly that rule. Have a look at below example. I have not changed the interface, just parts of the implementation. And I get exactly the strange behavior that Mr. Meyers warns for.
#include <iostream>
#include <cassert>
using namespace std;
class Telegram
{
public:
int getType(){ return -1; } // -1 = invalid type
};
class LoginTelegram : public Telegram
{
public:
static int getType() { return 0; }
};
class LocationTelegram : public Telegram
{
public:
static int getType() { return 1; }
};
int main()
{
LoginTelegram * t1 = new LoginTelegram;
Telegram * t2 = t1;
assert( t1->getType() == t2->getType() );
exit( 0 );
}
# 24 Re: Why static pure virtual function is not possible?
Well, you do! Your tricky implementation (non-virtual function calls pure virtual function) does not eliminate the fact that your interface violates exactly that rule.
treuss My friend,
my tricky implementation is a known method called:
"Generic Algorithm", I'm sure you can find reference
about it, I didn't find a specific item on Meyers EC++ & MEC++,
but maybe he mentions it too.
A classic example is an algorithm to find the volume of simple 3d shapes: a cube, a box and a cylinder. the following partial code
demonstrates the idea:
class cube{
protected:
int a,h;
public:
//constructor bla bla...
// "a Generic Algorithm": non-virtual func calls virtual func
float volume() { return h*area(); }
// THE virtual function
virtual float area( return a*a; }
};
class box: public cube{
protected:
int b;
public:
// constructor bla bla..
virtual float area( return a*b; }
};
class cylinder: public cube{
public:
cylinder(int la, int lh):cube(la,lh){}
virtual float area( return a*a*PI; }
};
cube c(4,10);
box b(4,5,10);
cylinder cyl(7,9);
// here is the beauty of this technique
// the generic algorithm for volume is height*area
// and its identical to all the deriveds, so we put it in the base
// and let deriveds inherit it, while each derived implement
// its own area() func.
cout << c.volume() << b.volume << cyl.volume() << endl;
}
of course, by changing the implemention and canceling the
dynamic linking the results are wrong. no need for assertion
to see it... :)
Guysl at 2007-11-9 0:54:22 >

# 25 Re: Why static pure virtual function is not possible?
It's also called Template Method, and there is an argument for never putting virtual functions in the public interface, only non-virtual. That way, all the code that varies down the hierarchy is non-public, and all the public code is non-varying. Indeed, in many cases a derived class will not have a public section at all, since it inherits all it needs from the base. I think a rigid adherence to that rule is a bit over the top, but it's worth keeping in mind.
# 26 Re: Why static pure virtual function is not possible?
posted by king
suppose this static methos call results in a call to this Pure Virtul method.
then?
the virtual table of the base class (this class only) will not have an entry for this pure virtual method...the rule says so.
and remember virtual methods r resolved at runtime...if a pointer is used
and so it wont always be possible to catch such errors at complie time...this means that the program is prone to crash.
.
sorry if I didn't get you well, my english is not so good as you
might think...
1.) You can't get a run time error, as much as i know, when calling
a virtual function via an object that doesn't have / inherited it,
because the linker complains at the point of the object decleration,
a way before the function itself is been called...
2.) There is no collision between names of static functions
and other functions, since the function name is just
a part of the full call. static func are called by className::
while other are called by object/pointer/reference.
Guy
Guysl at 2007-11-9 0:56:22 >

# 27 Re: Why static pure virtual function is not possible?
Graham,
Now I'm a bit confused.
using public non virtual funcs in base, that
call non public virtual funcs in deriveds falls in
that rigid rule, right?
Guysl at 2007-11-9 0:57:24 >

# 28 Re: Why static pure virtual function is not possible?
What I mean is that the Template method is very useful, but there are occasions when it seems wasteful:
class shape
{
public:
double area()
{
return do_get_area();
}
protected:
virtual double do_get_area() = 0;
};
This seems a bit excessive, just to keep virtual out of the public interface.
# 29 Re: Why static pure virtual function is not possible?
The Template method pattern is one of my favourites and I have been using it to fix the sequence of function calls. For example I had written a TiffConverter base class and its subclasses has to write the header and data differently. By making writeFile() public while do_writeHeader() and do_writeData() private, users of my class are forced to use writeFile() and hence cannot misused the other two functions in the wrong order.
class TiffConverter
{
public:
void writeFile(BYTE* data)
{
do_writeHeader();
do_writeData(data);
}
private:
virtual void do_writeHeader()=0;
virtual void do_writeData(BYTE* data)=0;
};
class CMYKTiff : public TiffConverter
{
private:
void do_writeHeader()
{
// Implementation of CMYK header for Tiff
....
}
void do_writeData(BYTE* data)
{
// Format the data for writing into the Tiff file
...
}
};
Kheun at 2007-11-9 0:59:23 >

# 30 Re: Why static pure virtual function is not possible?
Originally posted by Guysl
treuss My friend,
my tricky implementation is a known method called:
"Generic Algorithm" [...]
Oh, I didn't speak against your implementation. I spoke against your interface, which imho violates an essential rule. Your implementation makes sure that the violation of that rule does not lead to strange program behavior, I illustrated that with a different implementation (something that would often be implemented by a beginner in C++), the interface can lead to very strange program behavior, i.e. the [seemingly] same function called for the same object returning two different values.
A classic example is an algorithm to find the volume of simple 3d shapes: a cube, a box and a cylinder. the following partial code
demonstrates the idea:
[...]
There is nothing wrong with this example, as you do not inherit
float volume() in the derived classes.
But, quoting the moderator here (who probably quotes Mr. Meyer again):
Public inheritance means IS-A. This is the fundamental rule: there are no exceptions.
A cylinder is a cube ?
# 31 Re: Why static pure virtual function is not possible?
I spoke against your interface, which imho violates an essential rule.
Again, where is the violation?
the non virtual function in the base class isn't been overide.
There is nothing wrong with this example, as you do not inherit
code:------------------------float volume()------------------------
in the derived classes.
well,either my code for "static virtual function" doesn't
contain derived's overridig of a base's non virtual function.
as I said before, we can have an arguement of overriding a static function.
quote:
------------------------
Public inheritance means IS-A. This is the fundamental rule: there are no exceptions.
------------------------
A cylinder is a cube ?
Don't fall into interpretations of the real world,
in my computer-system-solution, yes, a cylinder IS-A cube!
they share common data, they have a common interface,
and thats the basis of inheritance.
Guysl at 2007-11-9 1:01:29 >

# 32 Re: Why static pure virtual function is not possible?
Originally posted by Guysl
Don't fall into interpretations of the real world,
in my computer-system-solution, yes, a cylinder IS-A cube!
they share common data, they have a common interface,
and thats the basis of inheritance.
That's commonly known as "Bad Design". You should try to stay in the real world as much as possible. This is essential for understanding software.
Data and interface is NOT the basis of inheritance.
Jeff
# 33 Re: Why static pure virtual function is not possible?
jfaust,
Maybe its my english, or my little experience,
but I meant to say that common is the basis
of inheritance. if I'm wrong please tell me what is.
Thinking deeper about your definition for one aspect
of "Bad Design" - I agree...
so, for my concrete example for Template Method
(a reminder: class cylinder inherited from class cube),
if I would change only the names of the classes
to something that describes better the real world,
then the design becomes better?
Guysl at 2007-11-9 1:03:27 >

# 34 Re: Why static pure virtual function is not possible?
Originally posted by Guysl
if I would change only the names of the classes
to something that describes better the real world,
then the design becomes better?
Yes. If you used better names to illustrate an example that more accurately describes real world relationships, you would have a better design. But note that although good names are important (and difficult to create) merely changing names will not give you a better design.
But it would be a better example.
Jeff