Static virtual functions?

G

gw7rib

I appear to need a static virtual member function, which it seems I
can't have. I'm trying to do something like the following:

class Base {
virtual void writetofile() = 0;
virtual void readfromfile() = 0;
(something here) char *name(); };

class Deriv1 : public Base {
virtual void writetofile();
virtual void readfromfile();
(ditto) char *name() { return "Deriv1"; } };

class Deriv2 : public Base {
virtual void writetofile();
virtual void readfromfile();
(ditto) char *name() { return "Deriv2"; } };

Now I want to write them to a file doing something like:

write (x -> name); x -> writetofile();

which requires name to be a virtual function. But I also want to do:

read(type);
if (strcmp(type, Deriv1::name) == 0) { x = new Deriv1; x ->
readfromfile(); }
if (strcmp(type, Deriv2::name) == 0) { x = new Deriv2; x ->
readfromfile(); }

which requires name to be a static member function.

Any suggestions? I want to avoid having to duplicate the names in
different places.

Thanks in advance.
Paul.
 
P

PeterAPIIT

As far as i know, a member function can be called using instance of
object or ::

A static function cannot be called from object.
 
M

Marcel Müller

I appear to need a static virtual member function, which it seems I
can't have. I'm trying to do something like the following:

class Base {
virtual void writetofile() = 0;
virtual void readfromfile() = 0;
(something here) char *name(); };

class Deriv1 : public Base {
virtual void writetofile();
virtual void readfromfile();
(ditto) char *name() { return "Deriv1"; } };

class Deriv2 : public Base {
virtual void writetofile();
virtual void readfromfile();
(ditto) char *name() { return "Deriv2"; } };

Now I want to write them to a file doing something like:

write (x -> name); x -> writetofile();

which requires name to be a virtual function. But I also want to do:

read(type);
if (strcmp(type, Deriv1::name) == 0) { x = new Deriv1; x ->
readfromfile(); }
if (strcmp(type, Deriv2::name) == 0) { x = new Deriv2; x ->
readfromfile(); }

which requires name to be a static member function.

Any suggestions? I want to avoid having to duplicate the names in
different places.


class Deriv1 : public Base {
public:
static const char* const name;
virtual const char *get_name() { return name; } };

const char* const Deriv1::name = "Deriv1";


Now you can get the name as constant from the class type as well as from
a class instance.


However, it seems that you want to implement your own (de)serialization.
There are solutions for this job around. You might want to give them a look.
First of all somewhere you should have an object type repository to
dispatch the deserialization. Virtual functions won't help you since you
do not have a typed object at this time. This is the job you did quite
ineffectively by the strcmp(type, Deriv1::name cascade. There are
significantly more sophisticated and faster solutions for this purpose.
Have a look at http://www.boost.org/libs/serialization/doc/tutorial.html

Furthermore, C++ programs should not contain char* objects. They are
nearly always risky. You should avoid char* wherever possible and use
std::string or const char* instead.


Marcel
 
W

witmer

As far as i know, a member function can be called using instance of
object or ::

A static function cannot be called from object.

Yes they can, but since statics cannot be virtual, you don't get
dynamic dispatch. The static function that will be called is
determined by the type of pointer/reference.
 
E

Erik Wikström

As far as i know, a member function can be called using instance of
object or ::

A static function cannot be called from object.

Actually it is the other way around a static function can either be
called by using Object.StaticFunc() or Class::StaticFunc(), but a member
can only be called using Object.MemberFunc().
 
R

Rolf Magnus

witmer said:
Yes they can, but since statics cannot be virtual, you don't get
dynamic dispatch.

Well, they can be called with the same syntax as non-static member
functions, but they still don't have an object inside the function.
 
C

coal

However, it seems that you want to implement your own (de)serialization.
There are solutions for this job around. You might want to give them a look.
First of all somewhere you should have an object type repository to
dispatch the deserialization. Virtual functions won't help you since you
do not have a typed object at this time. This is the job you did quite
ineffectively by the strcmp(type, Deriv1::name cascade. There are
significantly more sophisticated and faster solutions for this purpose.
Have a look athttp://www.boost.org/libs/serialization/doc/tutorial.html

I think that library needs work in terms of it's version support.
The author suggests placing version-related if statements in
classes. If followed, this approach makes a mush of the code
and leads to inefficiencies. For example, if the 1.2 server has
to support 1.1 ambassadors (clients), the B.ser approach will
only have one version of classes, which are intended to support both
1.1 and 1.2 releases, in the 1.2 server. Since those
classes have to support 1.2 ambassadors, they can't also efficiently
support 1.1 ambassadors.

More generally, B.ser's performance is weak in some simple
tests - http://www.webEbenezer.net/comparison.html.
I think it's possible to use both the Boost and Ebenezer
approaches in the same application. While the hybrid approach
would be more complicated than only using one of the approaches,
it offers an efficiency boost over B.ser.

Brian Wood
Ebenezer Enterprises
www.webEbenezer
 
G

gw7rib

class Deriv1 : public Base {
  public:
   static const char* const name;
   virtual const char *get_name() { return name; } };

const char* const Deriv1::name = "Deriv1";

Now you can get the name as constant from the class type as well as from
a class instance.

Thanks - that looks just the job. It needed an extra "const" after
get_name() but otherwise worked fine.
However, it seems that you want to implement your own (de)serialization.
There are solutions for this job around. You might want to give them a look.

I think the stuff I'm doing is, at least at the moment, too simple to
really justify this, but I'll bear it in mind if things get more
complicated. Thanks for the pointer.
Furthermore, C++ programs should not contain char* objects. They are
nearly always risky. You should avoid char* wherever possible and use
std::string or const char* instead.

You'll be pleased to hear that my program only uses chars in a few
small areas, but less pleased to hear that that's because it's a
Windows program and so uses TCHARs in most places. :)
But most of the char*s are indeed const.

Paul.
 

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

Similar Threads

Virtual destructor 3
Wrapper functions 1
Non virtual and inheritance 7
Virtual functions 0
virtual+static 7
Virtual function 2
virtual base classes, templates, and static functions 2
C Programming functions 2

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top