Archived

This topic is now archived and is closed to further replies.

Promiscuous Robot

virtual static members.

Recommended Posts

quote:
Original post by Promiscuous Robot
Basically I am just wondering if its possible, and if it''s something to be avoided, or has issues, or something.



Not possible. static methods run at class-level, while virtual methods run at object-level.



---- --- -- -
Blue programmer needs food badly. Blue programmer is about to die!

Share this post


Link to post
Share on other sites
The easiest way to tell if it is possible is to try it and see if the compiler accepts it. I don''t see any technical reason why you couldn''t have virtual static methods. The same arguement presented would be just as valid for arguing you couldn''t have static methods at all. The only issue that really matters though is whether the compiler will flag it as an error or not.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Is this C++ you''re talking about? If so "virtual static" doesn''t even make sense. static members have no object associated with them - they''re basically no different than a regular (non-member) function except that they''re in a different namespace. "virtual" is inherently concerned with the object heirarchy. No object, no virtual.

What are you *really* trying to do that you think you need "virtual static"?

-Mike

Share this post


Link to post
Share on other sites
i agree w/ lilbuddywizer, because what to say that you can't override a static function in a derived class?

I think it's perfectly legal, and u know what?

*adds virtual to a static member*
*hits compile*

well, msvc++ doesn't allow it, but hey, msvc isn't ansi.


Compiler Error C2576
'identifier' : virtual used for static member function


A static member function was declared as virtual.

The virtual function mechanism relies on the specific object that calls the function to determine which virtual function is used. Since this is not possible for static functions, they cannot be declared as virtual.


oh well...



Edited by - Succinct on February 1, 2001 6:12:08 PM

Share this post


Link to post
Share on other sites
Think about it.
A virtual static is an oxymoron.

You /can/ override static methods, but they cannot be called from a base class pointer. Static methods are not _thiscall's, so they don't get a vtable, so they can't be virtual because there's no way to resolve a virtual call without a this pointer.

Remember, you can call a static methods just using the class name, you don't need any pointer at all.

If you can determin which static method to use without using the this pointer, then there's no reason to make it virtual.
QED

Edited by - Magmai Kai Holmlor on February 1, 2001 6:25:50 PM

Share this post


Link to post
Share on other sites
Hmm.. yes yes I realize the stupidity of the request.. But I asked because it would''ve made my life easier..

Oddly enough I don''t even remember why I wanted one because I guess I designed around it...

oh well.

Share this post


Link to post
Share on other sites
quote:
Original post by Succinct
i agree w/ lilbuddywizer, because what to say that you can''t override a static function in a derived class?

I think it''s perfectly legal, and u know what?



Yup, you''re wrong. The ANSI C++ Standard and the nature of the qualifiers ''static'' and ''virtual'' dictate that they cannot be used together.

Depending on your compiler to define what is legal will cause no end of problems when you try to port your software, use another compiler, or the compiler changes (and yes, the latter happens regularly).


---- --- -- -
Blue programmer needs food badly. Blue programmer is about to die!

Share this post


Link to post
Share on other sites
Each instance of a given class with virtual functions has a hidden data member that points to the same vtable. That vtable exists independant of any instance of the class. A virtual static member function would simply require an entry in that vtable. You seem to argue that the compiler could not find that vtable without an instance of the class, but when you create an instance of that class it sets a hidden data member to point at that vtable so it must be able to find it without an instance. Virtual simply means it will go through a vtable to get to the function. Static means it will not pass a pointer to the instance to the function, i.e. this. There is nothing inherently conflicting about that. I would accept that other features of C++ used in combination with virtual and static would make for a conflicting or indeterminate situation. Virtual and static alone don''t create that situation.

You could argue that you could not call an overridden virtual static member function from a pointer to the base class, but that would only be true if the pointer was to an instance of the base class in which case you couldn''t call an overridden virtual member function either. If you were calling it as pointer->func then you have a vtable provided explicitly. If you were calling it as class::func then overriding has no relavence. So what the compiler should do is clear. It should follow the standard and the standard doesn''t allow it. There is most likely a reason the standard doesn''t allow it, but I don''t think that reason has been given yet.

Share this post


Link to post
Share on other sites
From the C++ ARM SS 10.2:
"The virtual specifier implies membership, so a virtual function cannot be a global (nonmember) (SS 7.1.2) function. Nor can a virtual function be a static member, since a virtual function call relies on a specific object for determining which function to invoke. A virtual function can be declared a friend in another class. An overriding function itself is considered virtual. The virtual specifier may be used for an overriding function in a derived class, but such use is redundant. A virtual function in a base class must be defined or declared pure (SS 10.3). "

Yes, the final period is bold. As in "end of discussion". If you got a problem with it, feel free to email ANSI or Stroustrup.

Share this post


Link to post
Share on other sites
Heres a little hope:

You can''t have a static virtual function, however you can call a virtual function from a static function.
eg:

CClass::StaticFunc(CClass* pClass)
{
pClass->VirtualFunction();
}

If that is any help.

Share this post


Link to post
Share on other sites
I didn''t argue that the ANSI standard allowed a static function to be virtual. My point is more that I cannot think of a situation where two instances of the same class have differant vtables. Since the specification implies that it can happen I assume that it can, but I still don''t know what situation that is. Perhaps it bothers you that I would like to understand what situation that is, but all I can say is that it bothers me more that the situation may exist and I don''t know it than that you will be irritated by desire to learn it.

Share this post


Link to post
Share on other sites
Forgive me
quote:


  
CClass::StaticFunc(CClass* pClass)
{
pClass->VirtualFunction();
}


HeheheheEHehehehehe...

...
Just becuase the constructs of a language don''t allow something doesn''t mean it can''t be added or isn''t available elsewhere.
Templatized methods, for instance, could easily be added and would not break any serious C++ rules.

Because of the way C++ realizes a static method, it cannot determine the originating class at run time. That doesn;t mean it never will, it would not be that impossible to add vtable baggage to statics - only statics & virtual static would be in this particular table. The clincher is, you won''t ever need to do this because you can determine at compile time which method to call, if you cast your code right. In order for the ''static'' nature of the call to remain intact, you must be able to resolve the call without a this pointer, which necessitates that you can determine which function to call at compile time, and negates the usefulness of a virtual call.

If you want to procede with this, you can create a bogus virtual method that simply calls the local static you really wanted to be virtual in each sub-class.

Magmai Kai Holmlor
- The disgruntled & disillusioned

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Original post by LilBudyWizer

I didn''t argue that the ANSI standard allowed a static function to be virtual. My point is more that I cannot think of a situation where two instances of the same class have differant vtables. Since the specification implies that it can happen I assume that it can, but I still don''t know what situation that is. Perhaps it bothers you that I would like to understand what situation that is, but all I can say is that it bothers me more that the situation may exist and I don''t know it than that you will be irritated by desire to learn it.



  
class A { ... };
class B : public A { ... };

void foo(A* p, A* q);


The question is, inside the function foo, do the objects (*p) and (*q) have the same vtable? Possibly, if pointers to two A objects were passed in. Different vtables if a pointer to a B was passed in with a pointer to an A. The programmer can''t tell.


Share this post


Link to post
Share on other sites
If virtual static functions were allowed it wouldn''t matter whether they have the same vtable. If it is a pointer to an instance of A then you want to call the function in A. If it is a pointer to B and B overrode the virtual function then you would want to call the function in B. Static wouldn''t change that. They would have two differant vtables, but the one you should use is the one you were passed.

Now I like Magmai''s arguement. The differance between class::function() and instance->function() does make for an inconsistancy since in one case virtual has a meaning and in the other it is completely irrelevant. It seems obvious that base::function() could not call derived::function() since multiple classes could be inherit from a single base class, but a programmer could easily believe it would although it would be technically impossible. I''ll buy that the inconsitancy is a valid reason to disallow it.

Share this post


Link to post
Share on other sites
There''s no easy way to have run-time polymorphism without instances:



struct base { virtual void function(); };
struct d1 : public base { void function() { cout << "d1"; } };
struct d2 : public base { void function() { cout << "d2"; } };

void some_function(base* const p)
{
p->function(); // which vtbl?
}



Besides, what you are talking about can be accomplished using templates. Templates provide compile-time polymorphism (of a sort). Virtual functions and inheritance provide run-time polymorphism. Both are useful; choose which one you need.

Share this post


Link to post
Share on other sites
Ok I see why I wanted this now. Look at this example:

  
class A
{
public:
// stuff


static virtual int funstuff ();

int otherstuff ();
};

int A::otherstuff ()
{
// ...

return funstuff ();
}

class B : public A
{
public:
// ...


// override

static int funstuff ();
};

void main ()
{
B b;

b.otherstuff ();
}


The idea being that the compiler ''knows'' which one to call because the call to the so-called ''virtual static'' is house inside the method A::otherstuff, it does have a vtable to work with..

Obviously its easy to work-around, and probably thats not even proper design or whatever (can you tell I''m an OOP guru?). I''ll compare it to the Simpson''s episode where Lisa couldn''t figure out that brain teaser and thought she was getting dumber and dumber. Sometimes things just take time to see .



--------------------------
I guess this is where most people put a famous quote...
"Everything is funnier with monkey''''s" - Unknown

Share this post


Link to post
Share on other sites
Hehe, you could create a data member that points to the static function. So the constructor for A would set it to one value and the constructor for B would set it to another. That would effectively be a static virtual function.

Share this post


Link to post
Share on other sites
If you have to call the static member function through a normal member function, it is pointless to make it static. Can you think of a reason why you would need virtual static member functions?

Edited by - null_pointer on February 3, 2001 5:28:37 PM

Share this post


Link to post
Share on other sites
There are practical uses for virtual static methods. Two examples that come to mind are related to resource management and file importing.

Say you designed a resource manager that bound files to runtime objects based on file extension. Classes for these objects could supply the applicable file extension(s) matching those objects. These would be static methods of the class, since the information represents information about the class as a whole, not individual object instances. However, they would also need to be virtual, since each subclass from the base resource object chooses its own extension(s) to support, and these choices can be made at runtime, not necessarily compile time.

A second example (although somewhat related to the first) would be a file importer. Say you have a collection of importer objects that support some kind of import class interface to convert one form of data into another, with the available importers determined at runtime (via plug-ins or whatnot). Since you would not want to have to instantiate an importer object just to see what import capabilities it has (i.e. what kind of data it imports and exports etc), it would be very handy to have this information available via the importer subclass itself, hence a static method. But once again, this method must be virtual, since importer subclasses are determined at runtime.

These are just a couple examples, and I''ve actually encountered plenty more in practice that make virtual static a very useful construct. Unfortunately C++ doesn''t support such a thing.

The solution I''ve adopted is simply to use a "class object" sort of pattern, where the "virtual static" methods are just normal virtual methods of the class object rather than the objects themselves, so I can query these class objects for overall class information rather than be forced to create instances for this purpose. By adding functionality to subclasses of the base "class object" via virtual functions, you get the behavior of virtual static functions even though C++ doesn''t allow them directly.

You can find an implementation of this in the Reflective Factory pattern, which I''ve posted up in gamedev.net''s patterns database.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Original post by Chris Hargrove

A second example (although somewhat related to the first) would be a file importer. Say you have a collection of importer objects that support some kind of import class interface to convert one form of data into another, with the available importers determined at runtime (via plug-ins or whatnot). Since you would not want to have to instantiate an importer object just to see what import capabilities it has (i.e. what kind of data it imports and exports etc), it would be very handy to have this information available via the importer subclass itself, hence a static method. But once again, this method must be virtual, since importer subclasses are determined at runtime.




I am not sure about this one, the whole point of inheritance and polymorphism is to not care about the type of data it imports exports. It should all be transparent.

Share this post


Link to post
Share on other sites
Bad design cripples code.

static implies that you don''t need an object. virtual implies that you don''t need a type. If you can''t know either, how would you access a virtual static member function? You MUST provide either the type or some data that can be used to find the type.

The easiest method is to merely extend the factory concept with a map of keys to a pair of per-class allocator and per-class data pointers. I just finished writing a factory class takes four template parameters, works with any polymorphic resource (not just C++ objects), stores per-class (as in static) data, allocates objects from a user-defined type value (i.e., a string containing a file extension), deallocates objects, and checks them for validity. Did I mention that it is only 30 lines (with readable spacing) and no macros?

It relies on other parts of my template library, but if you want to see it, I''ll post it.

Share this post


Link to post
Share on other sites