Unfortunately, my compiler (which happens to be VC++ 6.0) does not appear to
allow a method to be declared static virtual. And after a little research I
have gleaned that the C++ standard doesn't allow it either. This isn't a
major stumbling block; I'll probably work around it by declaring two
methods, one static and the other virtual, and have the virtual one call the
static one. However, this seems silly.
My question to the readers of this group is basically philosophical: why
isn't "static virtual" allowed?
As I understand it, "static" indicates that a method uses no instance data
and can therefore be called without an instance (using ::). Calling a
static method on an instance (using . or ->) is still perfectly legitimate.
"Virtual" ensures that a method call through a pointer always calls the
appropriate method, regardless of pointer type. It has no effect on method
calls that are not made through pointers.
It seems to me that these two attributes are entirely orthogonal, since one
affects only situations in which :: is used and the other affects only
situations in which -> is used. I can see no reason, either conceptual or
practical, that the following should not be legal C++:
class A {
public:
virtual static void f();
};
class B : public A {
public:
virtual static void f();
};
A a;
A* pa;
A::f(); // calls A::f(), needs "static"
a.f(); // calls A::f()
pa->f(); // calls A::f() or B::f() as appropriate, needs "virtual"
Not only does this seem perfectly sane -- and trivial to implement in any
compiler -- it would also be useful, at least to me in the present instance.
So why is it prohibited? Does anyone know?
-- Ben
To reply by email, replace "myth" with "math".
Would you be so kind to share that situation you're talking about?
>
> Unfortunately, my compiler (which happens to be VC++ 6.0) does not
appear to
> allow a method to be declared static virtual. And after a little
research I
> have gleaned that the C++ standard doesn't allow it either. This
isn't a
> major stumbling block; I'll probably work around it by declaring two
> methods, one static and the other virtual, and have the virtual one
call the
> static one. However, this seems silly.
>
> My question to the readers of this group is basically philosophical:
why
> isn't "static virtual" allowed?
>
> As I understand it, "static" indicates that a method uses no instance
data
> and can therefore be called without an instance (using ::). Calling a
> static method on an instance (using . or ->) is still perfectly
legitimate.
> "Virtual" ensures that a method call through a pointer always calls
the
> appropriate method, regardless of pointer type. It has no effect on
method
> calls that are not made through pointers.
What do you mean "it has no effect"?
>
> It seems to me that these two attributes are entirely orthogonal,
since one
> affects only situations in which :: is used and the other affects only
> situations in which -> is used. I can see no reason, either
conceptual or
> practical, that the following should not be legal C++:
>
> class A {
> public:
> virtual static void f();
> };
>
> class B : public A {
> public:
> virtual static void f();
> };
>
> A a;
> A* pa;
Uninitialised pointer. BAD!!!
>
> A::f(); // calls A::f(), needs "static"
> a.f(); // calls A::f()
> pa->f(); // calls A::f() or B::f() as appropriate, needs
"virtual"
Dereferencing of uninitialised pointer. Undefined behaviour!!!
>
> Not only does this seem perfectly sane -- and trivial to implement in
any
> compiler -- it would also be useful, at least to me in the present
instance.
> So why is it prohibited? Does anyone know?
Access to a virtual function is resolved through an instance of the
class.
That's the essence of virtuality of member functions. How, I am asking,
is the compiler going to resolve the access if the instance is NOT to be
used? It seems rather a contradiction to me...
I would like to see the implementation of those functions. What use do
you have for virtuality?
My guess is that your design is what we, Russians, call "pulling your
trousers on over your head". Share the design with us, and we may be
able to give you more insight on possible solutions.
Victor
--
Please remove capital A's from my address when replying by mail
You might bypass the limitation using singletons.
Regards,
Alex V.
Ben Rudiak-Gould wrote in message ...
>I have encountered a situation in which it would be convenient to be able
to
>declare a static virtual method in a class. It needs to be virtual because
>it's called through interface pointers in code which doesn't have access to
>the implementation. It would be nice if it were static, because in the
main
>program I would like to call it without necessarily having a class instance
>around. (It doesn't use any instance variables.)
>
>Unfortunately, my compiler (which happens to be VC++ 6.0) does not appear
to
>allow a method to be declared static virtual. And after a little research
I
>have gleaned that the C++ standard doesn't allow it either. This isn't a
>major stumbling block; I'll probably work around it by declaring two
>methods, one static and the other virtual, and have the virtual one call
the
>static one. However, this seems silly.
>
>My question to the readers of this group is basically philosophical: why
>isn't "static virtual" allowed?
>
>As I understand it, "static" indicates that a method uses no instance data
>and can therefore be called without an instance (using ::). Calling a
>static method on an instance (using . or ->) is still perfectly legitimate.
>"Virtual" ensures that a method call through a pointer always calls the
>appropriate method, regardless of pointer type. It has no effect on method
>calls that are not made through pointers.
>
>It seems to me that these two attributes are entirely orthogonal, since one
>affects only situations in which :: is used and the other affects only
>situations in which -> is used. I can see no reason, either conceptual or
>practical, that the following should not be legal C++:
>
> class A {
> public:
> virtual static void f();
> };
>
> class B : public A {
> public:
> virtual static void f();
> };
>
> A a;
> A* pa;
>
> A::f(); // calls A::f(), needs "static"
> a.f(); // calls A::f()
> pa->f(); // calls A::f() or B::f() as appropriate, needs "virtual"
>
>Not only does this seem perfectly sane -- and trivial to implement in any
>compiler -- it would also be useful, at least to me in the present
instance.
>So why is it prohibited? Does anyone know?
>
>
Well, first let me mention that there is no "C++'s vtable system".
There are virtual functions. But the Standard doesn't require any
particular way of implementing them. That said, you're probably
right that virtual functions mechanism is what you want.
You will need to declare a base class that your Y will know about.
The classes in X will be derived from that base class. If you want
they will override some virtual member functions. So far so good...
>
> This isn't quite the usual application of vtables, since there's only one
> implementation in X of the interfaces in question. On the other hand,
from
> Y's perspective there are many implementations, corresponding to different
> versions of X.
Why do you say it's unusual? From the design question, the
"dynamicism" of the objects exists beyond the runtime. It stretches
across multiple runs along the lifetime of the design. So what?
>
> X itself doesn't need the vtables -- it could bypass them entirely, if
there
> were any convenient way to indicate that in C++. And in the case of
methods
> whose behavior depends only on their parameters, I could also bypass the
> need to have a class instance entirely. But only if I could declare the
> method static virtual.
The point is that the interface of the class your X program is going
to use is dictated by Y. The design is determined by the Y side of the
final combination, not by X...
Well, what you're looking for is "callbacks". That is the usual
way of implementing dynamic backward binding (class-independent
calls from some code that doesn't change to the code that might).
Y:
----------------------------------
typedef bool (*callback)(int);
void dosomestuff(int a, callback c)
{
if (c(a))
{
// special processing
}
}
----------------------------------
X:
----------------------------------
typedef bool (*callback)(int); // you should put that into
// the header associated with
// Y library.
bool mycallback1(int a)
{
return a > 2;
}
bool mycallback2(int a)
{
return a < -42;
}
int main()
{
dosomestuff(5, mycallback1);
dosomestuff(5, mycallback2);
}
----------------------------------
>
> This isn't the only situation I can think of in which static virtual
> functions might be useful. In this same program I also have some genuine
> polymorphic types, and in at least one case the interface includes some
> functions that return per-class information: e.g.
>
> class AbstractInterface {
> // ...
> virtual bool IsAFoo() = 0;
> // ...
> };
>
> class Foo : public AbstractInterface {
> // ...
> bool IsAFoo() { return true; }
> // ...
> };
>
> class Bar : public AbstractInterface {
> // ...
> bool IsAFoo() { return false; }
> // ...
> };
>
> I can't see why it shouldn't be possible to declare IsAFoo() to be static,
> so that I could write Foo::IsAFoo() for example. (Yes, in this case it's
> obvious that Foo is a Foo, but in general this notation could be much
> clearer than the alternatives.)
Again, go the distance and have a static member a pointer to which
the virtual function will return. There will be NO BINDING at all.
The methods will only have to be compatible by the parameter types
and return value types, however, there would be no limitation on the
number of them or on their existence:
typedef bool (*Method)();
class AbstractInterface {
// ...
virtual Method WhatToCall() = 0;
// ...
};
class Foo : public AbstractInterface {
// ...
static bool Method1();
static bool Method2();
virtual Method WhatToCall()
{
if (condition)
return Method1;
else
return Method2;
}
// ...
};
class Bar : public AbstractInterface {
// ...
static bool Method1111();
static bool Method2222();
virtual Method WhatToCall()
{
return Method1111;
}
// ...
};
That actually would give you MUCH MORE flexibility than static virtual
functions.
>
> Ultimately, though, I'm not trying to argue that static virtual functions
> are useful. What I'm trying to argue is that the "static" and "virtual"
> properties are independent, and that therefore it makes no more sense to
> outlaw the combination than it does to outlaw, say, a virtual const
> function. You're trying to argue that the properties do interfere, like
> static and const for example. But in the three replies I've read so far I
> haven't seen a convincing argument for this.
>
> > > "Virtual" ensures that a method call through a pointer always calls
> > > the appropriate method, regardless of pointer type. It has no
> > > effect on method calls that are not made through pointers.
> >
> > What do you mean "it has no effect"?
>
> What I mean is that if you have a variable foo of type Foo, and a method
bar
> in Foo, then foo.bar() will always call Foo::bar(), regardless of whether
> bar is declared virtual and regardless of what other classes may derive
from
> Foo. Therefore, any C++ compiler is perfectly justified in converting
this
> to a direct call to Foo::bar() and skipping the vtable lookup entirely.
In
> fact, this is always the case with calls made on explicit instances of an
> object. Only when calls are made through pointers (or references; should
> have mentioned that) is it ever necessary to do a vtable lookup.
>
> Just to be sure, I actually wrote a little program to verify this
assertion.
> Here it is:
>
> #include <iostream>
>
> class Foo {
> public:
> virtual void f() { std::cout << "Foo\n"; }
> };
>
> class Bar: public Foo {
> public:
> virtual void f() { std::cout << "Bar\n"; }
> };
>
> void g(Foo foo) {
> foo.f();
> }
>
> int main() {
> Bar bar;
> g(bar);
> return 0;
> }
>
> As I expected, this program printed "Foo" and not "Bar" on my system. In
> fact, if it printed "Bar", then the C++ type system would be badly broken.
I see. I thought you meant anything but pointers. References work
just as well, mind you.
>
> I doubt there are any C++ compilers in existence which don't make this
> simple optimization. Hence my statement that "virtual" only affects calls
> through pointers.
>
> > > A a;
> > > A* pa;
> >
> > Uninitialised pointer. BAD!!!
> >
> > [...]
> >
> > Dereferencing of uninitialised pointer. Undefined behaviour!!!
>
> I assumed that people would be able to figure out that my example left out
> some (notional) intermediate code that wasn't relevant to my point. If
> you're going to be picky, you could also point out that there's no main()
> function, or that the method calls are illegal in global scope.
Well, it's not clear from your post whether you were simply leaving
some unimportant stuff out or you didn't understand some stuff. Please
forgive me if I offended your sense of self-esteem. That was not my
intent.
>
> > My guess is that your design is what we, Russians, call "pulling your
> > trousers on over your head". Share the design with us, and we may be
> > able to give you more insight on possible solutions.
>
> This is actually a very good point. My problem is described above, and I
> would be most grateful for any improved solutions that you or another
reader
> of this group could provide. (Other than declaring the functions in
> question as non-static, which I figured out myself. :-) )
I hope that passing to the dynamic library the poiters to the
function the library is to call will suit your needs.
There is one thing about your explanation that I do not understand. Why
don't you just define your method as a virtual instance method? This will do
the job for you.
My suspicion is that you are concerned about the extra parameter passed to
an instance method. However, if your instance method does not use this
parameter, I would expect the compiler to be able to optimize the call so
that the parameter is not passed to the method. As a general rule you should
not try to do optimizations that the compiler will probably do also.
/Per
Basically, I have a program X which loads a dynamically-linked library Y at
run time. X passes C++ object pointers to Y, and Y needs to call methods on
these pointers. It cannot call them directly because X does not export
them, and it cannot link its own copies because I want to be able to change
X without recompiling Y. Therefore, the calls must be made through some
sort of indirect system. C++'s vtable system seems well-suited to this.
This isn't quite the usual application of vtables, since there's only one
implementation in X of the interfaces in question. On the other hand, from
Y's perspective there are many implementations, corresponding to different
versions of X.
X itself doesn't need the vtables -- it could bypass them entirely, if there
were any convenient way to indicate that in C++. And in the case of methods
whose behavior depends only on their parameters, I could also bypass the
need to have a class instance entirely. But only if I could declare the
method static virtual.
This isn't the only situation I can think of in which static virtual
functions might be useful. In this same program I also have some genuine
polymorphic types, and in at least one case the interface includes some
functions that return per-class information: e.g.
class AbstractInterface {
// ...
virtual bool IsAFoo() = 0;
// ...
};
class Foo : public AbstractInterface {
// ...
bool IsAFoo() { return true; }
// ...
};
class Bar : public AbstractInterface {
// ...
bool IsAFoo() { return false; }
// ...
};
I can't see why it shouldn't be possible to declare IsAFoo() to be static,
so that I could write Foo::IsAFoo() for example. (Yes, in this case it's
obvious that Foo is a Foo, but in general this notation could be much
clearer than the alternatives.)
Ultimately, though, I'm not trying to argue that static virtual functions
#include <iostream>
void g(Foo foo) {
foo.f();
}
I doubt there are any C++ compilers in existence which don't make this
simple optimization. Hence my statement that "virtual" only affects calls
through pointers.
> > A a;
> > A* pa;
>
> Uninitialised pointer. BAD!!!
>
> [...]
>
> Dereferencing of uninitialised pointer. Undefined behaviour!!!
I assumed that people would be able to figure out that my example left out
some (notional) intermediate code that wasn't relevant to my point. If
you're going to be picky, you could also point out that there's no main()
function, or that the method calls are illegal in global scope.
> My guess is that your design is what we, Russians, call "pulling your
> trousers on over your head". Share the design with us, and we may be
> able to give you more insight on possible solutions.
This is actually a very good point. My problem is described above, and I
would be most grateful for any improved solutions that you or another reader
of this group could provide. (Other than declaring the functions in
question as non-static, which I figured out myself. :-) )
How about these ways:
(1) call the function through a pointer, a reference, or an actual instance;
the call is resolved through the ordinary virtual-call mechanism and the
function is called, but without the hidden "this" argument.
(2) call the function explicitly with class::func(), like a non-virtual
static method.
Ultimately, a static function is just one which doesn't take a "this"
pointer. There's no reason it can't be called in exactly the same ways as a
non-static function. All that "static" does is give you an additional way
of calling it ((2) above). It doesn't place any restrictions on other ways.
Try it out: if X has a static method foo(), and x is an instance of X, then
x.foo() is legal and identical to X::foo(). Same thing for px->foo() if px
is a Foo*.
> I would guess that the Standard writers saw
> those two declarations as contradictory, so they didn't allow for it.
You're probably right, but unless I'm still missing something (which is
possible) they were no more clear-headed in doing so than they were in
trying to introduce "noalias" to ANSI C.
> You might bypass the limitation using singletons.
Solving my immediate problem won't be that hard. I was mostly just curious
about this peculiarity of C++.
Unfair paraphrase:
> It cannot call them directly because X does not export
> them,
> ...
> Therefore, the calls must be made through some
> sort of indirect system.
>
In other words, you're looking for a workaround for a previous design
decision. <g>
--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Contributing Editor, C/C++ Users Journal (http://www.cuj.com)
It doesn't represent a cohesive design concept.
Virtual function calls need to be resolved not only from call sites outside
the class, but from calls within class member functions as well. A member
function needs a "this" pointer to correctly resolve the virtual function
call. But static functions don't have a this pointer.
As I understand it, the standards committee is reluctant to add features
to the language unless there is a clear benefit to the new feature, and
you cannot implement that feature using existing techniques.
On the surface, your suggestion looks reasonable:
// Current standard requires __cplusplus to be equal
// to 199711L, with future versions replacing it with
// a greater value.
#if __cplusplus > 199711L
#define VIRTUAL virtual
#else
#define VIRTUAL
#endif
class T
{
public:
VIRTUAL static void f();
};
class U : public T
{
public:
virtual static void f();
};
int main()
{
T t;
U u;
t.f(); // Statically bound, call T::f(); (current behaviour)
u.f(); // Statically bound, call U::f(); (current behaviour)
T::f(); // explicit call
U::f(); // explicit call
f(); // Ill-formed - no function ::f();
// Ah, here's the problem - the current behaviour of static
// functions:
T * tptr=&t;
tptr->f(); // Use dynamic binding to call T::f(), without passing
// the implicit 'this' argument.
tptr = &u;
tptr->f(); // Use dynamic binding to call U::f(), without passing
// the implicit 'this' argument.
}
Your new feature would break existing code, which relies on the static
type of 't' to invoke the static function. In the example above, under
the current rules t->f(); will be statically bound to T::f(). This could
have a significant impact on existing code.
No, wait a minute, it can't break existing code. "virtual static" is
currently disallowed, so there is no existing code to break. The
behaviour would be identical to making a non-virtual, non-static member
function virtual:
class T1
{
public:
void f();
};
class U1 : public T1
{
public:
void f();
};
int main()
{
T1 t1;
U1 u1;
t1.f(); // Statically bound, call T1::f();
u1.f(); // Statically bound, call U1::f();
T1 * t1ptr=&t1;
t1ptr->f(); // Calls T1::f() because it's statically bound.
t1ptr = &u1;
t1ptr->f(); // Still calls T1::f() because T1::f() is not virtual
}
If you present a clear case to the standards committee, you might get it
on the agenda for the next revision of the standard. At this point,
though, the committee is concentrating solely on defects and problems
with the standard - ISO rules require a minimum of five years between
revisions of a standard.
--
Jim
This message was posted using plain text only. Any hyperlinks you may
see were added by other parties without my permission.
I do not endorse any products or services that may be hyperlinked to
this message.
Sent via Deja.com http://www.deja.com/
Before you buy.
This is a FAQ. It's been asked, and discussed to death, both here and
on comp.std.c++. So, the standards committee members are well aware of
this idea, though I don't think anyone has submitted an official
proposal? It'll be a long time before such a proposal will be
considered, however, as the standard is locked into nothing but DRs for
a while.
--
William E. Kempf
Software Engineer, MS Windows Programmer
Actually, it does, and there are languages that have virtual statics.
In C++ there's only one ambiguity that would have to be clarified.
> Virtual function calls need to be resolved not only from call sites
outside
> the class, but from calls within class member functions as well.
It sounds like you've hit on the ambiguity here, but the rest of this
paragraph makes me wonder.
> A member
> function needs a "this" pointer to correctly resolve the virtual
function
> call. But static functions don't have a this pointer.
The fact that static functions don't have a this pointer is (nearly)
irrelevant. Let's look at the different ways of calling:
a.foo(); (or a->foo();)
This will use the virtual call method of invocation, it just won't
pass a "this" pointer.
A::foo();
This will use the static call method of invocation.
void A::bar()
{
A::foo();
}
This too will use the static call method of invocation.
void A::bar()
{
this->foo();
}
This will use the virtual call method of invocation, it just won't
pass a "this" pointer.
void A::bar()
{
foo();
}
This is where the ambiguity exists. If A::bar() is static the only
avenue open to the compiler is to call A::foo() statically since
there's no instance to call off of. If A::bar() isn't static, however,
we have to choose one method of invocation. The best choice is to use
the virtual call method of invocation, since that's consistent with the
concept that "this->foo();" is the same as just "foo();" within member
functions. This makes understanding the call mechanism a little more
complex for human readers, but it's consistent, simple and well defined
as far as the compiler is concerned.
Again, this is a FAQ that's been talked to death. Do search on
DejaNews for past discussions.
> So, the standards committee members are well aware
> of
> this idea, though I don't think anyone has submitted an official
> proposal?
That's why I suggested he come up with a clear case for it - if no one
requests it, the committee won't (may not) act on it. Kind of like the
lottery - you can't win if you don't buy a ticket.
Another route, by the way, would be to get a compiler vendor to
implement the scheme. Part of the job of the standardization committee
is to codify existing practise.
> It'll be a long time before such a proposal will be
> considered, however, as the standard is locked into nothing but DRs
> for a while.
Yes, I pointed that out.
--
Jim
This message was posted using plain text only. Any hyperlinks you may
see were added by other parties without my permission.
I do not endorse any products or services that may be hyperlinked to
this message.
Static means class level access. You don't need an object to invoke
that method. Even when you invoke a static method on an object, it is
essentially same as invoking that method at a class level. No object's
data can be used. Only class level data can be used.
Virtual means, take a decision at the run-time, depending on the
object's type.
These two are so contradictory to one another, that they cannot be
together.
Thanks,
Sai Pulugurtha
Brainbench MVP for C++
http://www.brainbench.com
In article <J1Qz5.21653$ks.9...@newsread1.prod.itd.earthlink.net>,
"Ben Rudiak-Gould" <be...@myth.berkeley.edu> wrote:
> I have encountered a situation in which it would be convenient to be
able to
> declare a static virtual method in a class. It needs to be virtual
because
> it's called through interface pointers in code which doesn't have
access to
> the implementation. It would be nice if it were static, because in
the main
> program I would like to call it without necessarily having a class
instance
> around. (It doesn't use any instance variables.)
>
> Unfortunately, my compiler (which happens to be VC++ 6.0) does not
appear to
> allow a method to be declared static virtual. And after a little
research I
> have gleaned that the C++ standard doesn't allow it either. This
isn't a
> major stumbling block; I'll probably work around it by declaring two
> methods, one static and the other virtual, and have the virtual one
call the
> static one. However, this seems silly.
>
> My question to the readers of this group is basically philosophical:
why
> isn't "static virtual" allowed?
>
> As I understand it, "static" indicates that a method uses no instance
data
> and can therefore be called without an instance (using ::). Calling a
> static method on an instance (using . or ->) is still perfectly
legitimate.
> "Virtual" ensures that a method call through a pointer always calls
the
> appropriate method, regardless of pointer type. It has no effect on
method
> calls that are not made through pointers.
>
> It seems to me that these two attributes are entirely orthogonal,
since one
> affects only situations in which :: is used and the other affects only
> situations in which -> is used. I can see no reason, either
conceptual or
> practical, that the following should not be legal C++:
>
> class A {
> public:
> virtual static void f();
> };
>
> class B : public A {
> public:
> virtual static void f();
> };
>
> A a;
> A* pa;
>
> A::f(); // calls A::f(), needs "static"
> a.f(); // calls A::f()
> pa->f(); // calls A::f() or B::f() as appropriate,
needs "virtual"
>
> Not only does this seem perfectly sane -- and trivial to implement in
any
> compiler -- it would also be useful, at least to me in the present
instance.
> So why is it prohibited? Does anyone know?
>
> -- Ben
>
> To reply by email, replace "myth" with "math".
>
>
A common misconception, maybe even why it wasn't originally thought of
in C++, but it's not true. They are not contradictory concepts. In
fact, there are languages that support virtual static methods. It's
also an idiom that can be very useful. It's quite possible that it may
even be included in C++ some day.
--
William E. Kempf
Software Engineer, MS Windows Programmer
The lottery is very fair. You have the same chance of winning whether you
buy a ticket or not.
Your chances of winning if you do not buy a ticket are *exactly* zero.
--
Jim
This message was posted using plain text only. Any hyperlinks you may
see were added by other parties without my permission.
I do not endorse any products or services that may be hyperlinked to
this message.
To expand on this, there is no "this" pointer passed to a static function,
the address of the instance that is not used with a static function.
The purpose of virtual functions is to allow you to take a pointer to
a base class, set it equal to the address of the derrived class object,
and have the code determine at run time the appropriate function to
execute.
Simply put: virtual functions NEED a pointer, static functions DON'T HAVE
a pointer. Thus, the two are mutually exclusive.
--
Calvin Henry-Cotnam
Richmond Hill, Ontario, Canada
Yes indeed.
X is actually a shared library itself, and lives in the search path, so it's
not inconceivable that it could in fact export those symbols. But I was
afraid that name-mangling would make it even less likely that plugins (Y)
could be developed using other compilers, or even other versions of the same
compiler.
On the other hand, I could just determine the name-mangling conventions used
by other compilers for these functions, and export those too as aliases...
Hmm...
But then I'd have to include all of my utility classes' innards in the
public header file, which is already too baroque as it is.
Also, it would make it difficult if not impossible for another application
to support X's plugins through emulation (and yes, that is a distinct
possibility).
I think I'd better stick with callbacks.
I guess the resolution of this debate depends on how you test for
floating-point equality...
Such as?
I understand delphi kind of has static virtuals (even static virtual
ctors!). But in that language, the class is actually an object with a
run-time existence. There are no meta-classes in c++, and class identity
all but disappears. (still, a faded existence in RTTI)
It all depends what we mean by static. If we mean "resolved at compile time"
(as in static type checking) then clearly virtual static is oxymoronic. If
we take the oo meaning "applies to the class, but not to instances of the
class (other than by association)" then we must accept that the class has
identity. This takes us away from c++.
Trying not to be controversial, I'll point out the C++ is a very static
language:
1) objects don't change class.
2) "class" in c++ provide the "intension" of the class - that is, the
definition of membership. This definition is frozen (or static, to overload
the term) once the code is compiled.
To model metaclasses in c++ using static members is a poor substitute for
the more tedious task of creating class factories, etc.
Static members should be seen as a packaging option, not an oo expression.
Whose paradox was it? Russell's?
Some sets are members of themselves (eg. the set of abstract ideas, which is
itself an abstract idea).
Let S be the set of sets that are _not_ members of themselves. Is S a
member of itself?
> In C++ there's only one ambiguity that would have to be clarified.
[snip]
> void A::bar()
> {
> this->foo();
> }
> This will use the virtual call method of invocation, it just won't
> pass a "this" pointer.
And if bar() is static, then it didn't get a "this" pointer.
So where does the "this" pointer come from, pray tell?
Maybe its a pointer some metaclass object, ala delphi, but we'd still need
an implicit argument.
If bar() is static, then the code is ill formed - it doesn't matter if
foo() is static or non-static, virtual or non-virtual, there is no
"this" member in a non-static function.
Actually, it hasn't been discussed all *that* much. I just looked it up
in DejaNews, and the most recent discussion of why static virtuals are
not allowed was back in January. There were about four or five threads
along the lines of "How can I get around it?"
> Simply put: virtual functions NEED a pointer, static functions DON'T
> HAVE
> a pointer. Thus, the two are mutually exclusive.
Nope. You're looking through the wrong end of the telescope.
The 'this' pointer is simply an argument passed to the function. By the
time the compiler generates the machine code to push the arguments on
the stack (or otherwise pass the arguments) the compiler has already
gone through the process of name lookup, overload resolution, and
function binding.
There is no reason not to allow static virtual functions.
> ... there is no
> "this" member in a non-static function.
well, that's a new one :-)
Typo accepted
> > It all depends what we mean by static...
I think the catch all definition of static is "retains state".
Though that doen't quite mean "has internal linkage" does it!
but subsequent function binding may be required ...
>
> There is no reason not to allow static virtual functions.
except that these static functions would need an implicit argument for the
"static this".
A snippet of code is worth a thousand words:
struct B
{
static void d() {f();}
static virtual void e() {f();}
static virtual void f() {g1();}
static g1();
static g2();
};
struct D : B
{
static virtual void f() {g2();}
};
D::d(); // calls g1() or g2()?
D::e(); // calls g1() or g2()?
Under the current rules, if a member function is invoked from inside a
non-static member function, then an unqualified name is treated as if
you wrote "this->" followed by the function name.
If a member function is invoked from inside a static member function,
then an unqualified name is treated as if you wrote "T::" followed by
the function name (where T is the class whose member function you are
defining).
The standard may not define the name lookup and binding in exactly those
terms, but that is the effect of the behaviour.
Since both D::d and D::e are static members, the function call will be
resolved statically to B::g1() in each case - exactly as expected.
I believe Small Talk. I know that at least 3 others were mentioned in
previous threads on this topic... I just don't recall them.
> > In C++ there's only one ambiguity that would have to be clarified.
>
> [snip]
>
> > void A::bar()
> > {
> > this->foo();
> > }
> > This will use the virtual call method of invocation, it just
won't
> > pass a "this" pointer.
>
> And if bar() is static, then it didn't get a "this" pointer.
Making the above code illegal, rendering the rest of your comments here
moot. In other words, the above syntax will only work for non-static
methods.
> So where does the "this" pointer come from, pray tell?
There is none. Remember, the above is only legal for non-static
methods.
--
William E. Kempf
Software Engineer, MS Windows Programmer
No, foo() was intended to be the "virtual static" method. I varied bar
() through out the discussion from static to non-static to illustrate
differences in calling conventions.
No they don't - there is no virtual static.
> Under the current rules, if a member function is invoked from inside a
> non-static member function, then an unqualified name is treated as if
> you wrote "this->" followed by the function name.
>
> If a member function is invoked from inside a static member function,
> then an unqualified name is treated as if you wrote "T::" followed by
> the function name (where T is the class whose member function you are
> defining).
hence the term "static" as in statically resolved.
>
> The standard may not define the name lookup and binding in exactly those
> terms, but that is the effect of the behaviour.
>
> Since both D::d and D::e are static members, the function call will be
> resolved statically to B::g1() in each case - exactly as expected.
>
but we have "virtual" - as in resolved based on run-time type. (we must
therefore intepret "static" in "static virtual" to mean "applies to the
class" not "statically resolved".) To match with the binding behaviour of
non-static member functions, we expect both D::d and D::e to resolve to
B::g2().
My point is that to implement this, there would need to be additional type
information (a "static this" or "class this") passed in an implicit argument
to both non-virtual and virtual static member functions.
what do you mean by static virtual and how would that be implemented?
static functions can be called by
ClassName::MethodName(); //no instance of object necessary
How would this work with a virtual function?
This is the only reason I can think of to declare a (member) function
static, so why would anyone want static virtual? If you want to access
static data you can do that from a normal member function.
Will
--
Will\,n 'wil
1. The Power of choosing, 2. Power to control, 3. The choice or
determination of one who has authority, 4. Strong wish
"You might want a static virtual member function so it can be called
from a static function in the base class."
In this case you need to ask why the calling function is static. As I
said in the last post, the only reason I see for a member function
being static is so it can be called without a this pointer. If at any
point during it's execution (including called functions) it needs a
this pointer then it shouldn't be static.
Apologies for the double post.
Perhaps I should rephrase the original statement - the rules do not have
to be changed to resolve which member function should be called.
>
> > Under the current rules, if a member function is invoked from inside
a
> > non-static member function, then an unqualified name is treated as
if
> > you wrote "this->" followed by the function name.
> >
> > If a member function is invoked from inside a static member
function,
> > then an unqualified name is treated as if you wrote "T::" followed
by
> > the function name (where T is the class whose member function you
are
> > defining).
>
> hence the term "static" as in statically resolved.
Yes, in that case it will be statically resolved. But when the call is
qualified with an identifier followed by a member access operator, then
the call can be dynamically dispatched.
>
> >
> > The standard may not define the name lookup and binding in exactly
those
> > terms, but that is the effect of the behaviour.
> >
> > Since both D::d and D::e are static members, the function call will
> > be
> > resolved statically to B::g1() in each case - exactly as expected.
> >
>
> but we have "virtual" - as in resolved based on run-time type. (we
> must
> therefore intepret "static" in "static virtual" to mean "applies to
> the
> class" not "statically resolved".)
Yes, I think you're getting it now. Once you get it firmly in your head
that "virtual" means dynamically bound, "static" means "applies to a
class", then it becomes easier to accept that "static virtual" is not an
oxymoron.
> To match with the binding behaviour of
> non-static member functions, we expect both D::d and D::e to resolve
> to
> B::g2().
No, we don't. Only when you *expect* dynamic dispatch to be involved,
which it clearly cannot be in the example you gave, because there is no
context in which to determine the dynamic type of the object. Therefore,
the static type must be used.
> My point is that to implement this, there would need to be additional
> type
> information (a "static this" or "class this") passed in an implicit
> argument
> to both non-virtual and virtual static member functions.
No. You simply use the existing the rule that a member function call
from within a static member is treated "as if" it explicitly used class
qualification. That is the current rule, so adding the feature involves
no extra overhead or information.
For example:
class T
{
public:
static void staticFunc();
virtual void virtFunc();
void nonVirtFunc();
static virtual void staticVirtFunc();
};
void f(T &t)
{
t.nonVirtFunc(); // binds to T::nonVirtFun
t.staticFunc(); // binds to T::staticFunc
t.virtFunc(); // dynamically bound
t.staticVirtFunc(); // dynamically bound
}
void T::nonVirtFunc
{
nonVirtFunc(); // statically bound
staticFunc(); // statically bound
virtFunc(); // Treated as "this->virtFunc()" therefore
// dynamically bound
staticVirtFunc(); // Treated as "this->staticVirtFunc()" therefore
// dynamically bound
}
void T::staticFunc()
{
// In all cases, all function calls are treated as if
// you wrote T::<function name>()
nonVirtFunc(); // error - requires an object
staticFunc(); // binds to T::staticFunc, always
virtFunc(); // error - requires an object
staticVirtFunc(); // statically bound to T::staticVirtFunc();
}
Except for the word "virtual" in front of the word "static" (and, of
course, the lines flagged as errors), the code above will compile and
call the functions I indicated on any current compiler. That is, if you
take steps to avoid the infinite recursion :-)
The order in which the compiler resolves function calls and generates
code is:
- Look up the name
- Determine which overloaded function (if any) applies
- Check access privileges
- If the function is virtual, apply dynamic dispatch mechanism,
otherwise bind statically.
- generate code that prepares arguments (including the implicit 'this'
if you are calling a non-static member function) and places the
arguments on the stack (or whatever the calling convention is).
So you can see it is quite easy to dynamically bind a static member
function - in the last step, you simply check if the function is
virtual, and if so you pass a pointer for it to use as 'this', if not
you omit that step.
--
Jim
This message was posted using plain text only. Any hyperlinks you may
see were added by other parties without my permission.
I do not endorse any products or services that may be hyperlinked to
this message.
You are severely misinterpreting the meaning of "static virtual". If
you have the following code:
void base::someStaticFunc()
{
someVirtualStaticFunc();
}
The "someVirtualStaticFunc()" that will be called is the base class's.
This must be so because we don't have an instance on which to do
dynamic dispatch.
To better illustrate "static virtual" let's show how it would be coded
by hand (i.e. with out the language syntax to handle it).
class base
{
public:
static void foo() { cout << "base::foo()" << endl; }
virtual void vfoo() { base::foo(); }
static bar() { foo(); }
};
class derived : public base
{
public:
static void foo() { cout << "derived::foo()" << endl; }
virtual void vfoo() { derived::foo(); }
static bar() { foo(); }
};
If we had "static virtual" methods than the above would be written with
foo and vfoo as a single method with the signature "static virtual void
foo()". Note that in base::bar() and derived::bar() we must do static
calls to foo() (i.e. we can't call vfoo()). This remains true when you
have "static virtual" methods (i.e. you'll call base::foo() from
base::bar() and derived::foo() from derived::bar()).
> In this case you need to ask why the calling function is static. As I
> said in the last post, the only reason I see for a member function
> being static is so it can be called without a this pointer. If at any
> point during it's execution (including called functions) it needs a
> this pointer then it shouldn't be static.
A "static virtual" doesn't get a "this" pointer, no matter how you call
it. However, if you call it with . or -> syntax, even though no "this"
pointer is passed, a dynamic dispatch mechanism will be employed to
determine which method to call. So while I agree with what you said,
you didn't go far enough to understand why "static virtual" methods are
useful and not contradictory.
--
William E. Kempf
Software Engineer, MS Windows Programmer
class SimpletonGreives: public Simpleton
{
public:
virtual static WhoTheHellRU() { cout << "Simpleton Greives!!!!\n"; }
};
Like that. Why could it not be implemented? Virtual mechanism is based on a table of
pointers, of which there's one instance _per class_. I say, it maps rather nicely into the
class-static members. The difference between static and NOT static is not whether the
instance is shared, but in an extra parameter, "this". Otherwise all these functions are
(physically) global and invoked via vtbl. A class-static func could be put there as well.
--
___ _ __ __ ___ _ ___ _____ ___ _ _
/ __|(_) \/ | _ \| | | __|_ __|/ _ \| \| |
\__ \| | |\/| | _/| |_| _| | | | (_) | |
|___/|_|_| |_|_| |___|___| |_| \___/|_|\_|
____ ___ ___ _ _ _ ___ ___ _
/ _ || _ \| __|(_) || | __|/ __|| |
| | __| /| _| | | || | _| \__ \|_|
\_____|_|_\|___||_|\__/|___||___/(_)
nosedive. 4 all your munging needs
> How would this work with a virtual function?
First, you could still call them via a generic pointer; second, you could perhaps create a
pointer-to-member and plug your funcs in it, just like you plug your object pointers into
a generic pointer variable. Of course (we're fantasizing anyway) the syntax could be
extended to handle that case.)
> This is the only reason I can think of to declare a (member) function
> static, so why would anyone want static virtual?
For the same reason you want _any_ function virtual. You confuse two notions, type scope,
and reference scope (though perhaps my choice of words isn't perfect here.)
Inheritance-based polymorphism is predicated on type, not instance of a type, iow, it's
got nothing to do with whether a member function operates on a particular instance, or
applies to the whole class. Say, I'd like to have a function that returns the name of the
type (?) Seems like a good candidate for a virtual static function. What I've always
thought, is that the choice of the term "static" to signify what we know as C++ static
members is unfortunate because of two other known kinds of "statics" in C/C++. Java books
tend to call them "class functions" (though the legal keyword is still "static"), which is
much better, imo.
> If you want to access
> static data you can do that from a normal member function.
>
> Will
>
> --
> Will\,n 'wil
> 1. The Power of choosing, 2. Power to control, 3. The choice or
> determination of one who has authority, 4. Strong wish
--
> Yes, I think you're getting it now. Once you get it firmly in your head
> that "virtual" means dynamically bound, "static" means "applies to a
> class", then it becomes easier to accept that "static virtual" is not an
> oxymoron.
I always undestood the word "static"
1. to be an overloaded keyword in C++.
2. to have distinct meanings within the normal terminology of the
language. (eg. static type checking is performed at compile time, objects
in static storage have fixed addresses.).
3. as an implementation of an OO concept, means "applies to the
extension of a class, not to an instance."
Without a clear definition of "static virtual" thus far, I have explored
several possible meanings.
I'm glad we have dispensed with the oxymoron, and are concentrating on the
3rd idea.
> > To match with the binding behaviour of
> > non-static member functions, we expect both D::d and D::e to resolve
> > to
> > B::g2().
> No, we don't. Only when you *expect* dynamic dispatch to be involved,
> which it clearly cannot be in the example you gave, because there is no
> context in which to determine the dynamic type of the object. Therefore,
> the static type must be used.
dynamic dispatch? isn't that what virtual means?
> > My point is that to implement this, there would need to be additional
> > type
> > information (a "static this" or "class this") passed in an implicit
> > argument
> > to both non-virtual and virtual static member functions.
Your idea of "static virtual" matches the OP's, and is broken. It amounts
to a compiler generated overload:
class B{static virtual sv(); };
is equivalent to:
class B {static sv(); virtual sv(){/* delegate to static sv */} };
Note that this sort of overloading is illformed. It offers very dubious
semantics.
> Class Simpleton
> {
> public:
> virtual static WhoTheHellRU() { cout << "Simpleton\n"; }
> };
>
>
> class SimpletonGreives: public Simpleton
> {
> public:
> virtual static WhoTheHellRU() { cout << "Simpleton Greives!!!!\n"; }
> };
>
> Like that.
i am waiting...
what do you mean by static virtual?
Your example does not make it clear how your idea of "virtual static"
differs from "static" (or for that matter, "virtual").
> > and how would that be implemented?
> ...
> The difference between static and NOT static is not whether the
> instance is shared ...
Sorry, can't agree with that. "static" means "fixed".
> ... but in an extra parameter, "this".
can't agree with that. "this" indicates self reference, which is a
perfectly valid concept in a context where the self is a class, not an
instance thereof. (although in that case, of course, the class is an
object.)
apparantly not. eg. virtual base class
still, "dynamic dispatch" is not required, to provide the behaviour I
expect.
> but we have "virtual" - as in resolved based on run-time type. (we must
> therefore intepret "static" in "static virtual" to mean "applies to the
> class" not "statically resolved".) To match with the binding behaviour of
> non-static member functions, we expect both D::d and D::e to resolve to
> B::g2().
ok, "virtual" doesn't necessarily mean resolved based on run-time type.
(For example, see virtual base class). It just means something like
"placeholder" for overriding.
In fact, the function binding of "static virtual" that I expect (different
from others) can be resolved at link time.
> My point is that to implement this, there would need to be additional type
> information (a "static this" or "class this") passed in an implicit
> argument to both non-virtual and virtual static member functions.
This additional information need not be available to the
programmer, need not exist beyond link time, and need not be used for
dynamic dispatch.
> It doesn't represent a cohesive design concept.
Thanks to those who have helped disabuse me of this prejudice.
In fact, "static virtual" would provide support for the "template method"
design pattern when we're using the class construct simply for packaging,
not for multiple instantiation. For example:
// the abstract class
class InterestCalculator
{
protected:
// "primitive operation" -
// virtual provides a placeholder for an overrider
static virtual float InterestRate()=0
public:
// the "template method"
static dollars Interest (dollars Principal, years Term)
{
// InterestRate() is resolved at link time.
return Principal * Term * (1.0 + InterestRate());
}
};
// the concrete class
class HighInterestCalculator : public InterestCalculator
{
protected:
// provide the primitive operation
static virtual float InterestRate() { return 0.20; }
};
dollars d = InterestCalculator::Interest (100.0, 1.0);
// error, can't use static member
// functions on a class with a
// pure virtual static member.
dollars d = HightInterestCalculator::Interest (100.0, 1.0);
// ok. d == 20.0
But since we can already do this just by dropping the static and using a
single instance, we don't miss anything by not having "static virtual".
... and gosh darn it, I can't make a "const mutable" data member either.
A "const mutable" is logically impossible as the two qualifiers are
mutually exclusive of each other. You can't say the same thing
about "static virtual", even though your first instinct is to do so.
The concepts aren't mutually exclusive since they define wholly
independent behaviors. Read the rest of this thread to understand how
(and maybe why) "static virtual" can be implemented.
--
William E. Kempf
Software Engineer, MS Windows Programmer
> In article <8r7t75$vkh$1...@nnrp1.deja.com>,
> banan...@my-deja.com wrote:
> >
> >
> > ... and gosh darn it, I can't make a "const mutable" data member
> either.
>
> A "const mutable" is logically impossible as the two qualifiers are
> mutually exclusive of each other. You can't say the same thing
> about "static virtual", even though your first instinct is to do so.
> The concepts aren't mutually exclusive since they define wholly
> independent behaviors. Read the rest of this thread to understand how
> (and maybe why) "static virtual" can be implemented.
You said something similar in response to one of my posts as well. I
think the problem a lot of people are having is that static and
virtual _are_ mutually exclusive. Static functions execute completely
independantly of any instance data, whereas virtual functions rely on
it intrinsicaly.
That's not to say I can't see the point in what you're arguing for. I
can. But I, like many others, was confused by your choice of the term
static virtual.
Members defined as you do are not static because they make use of
instance data, albeit only some of the time.
What is needed is some new specification that doesn't carry confusing
(to this point) baggage like static does. After all, and lets be
honnest here, static has too many meanings already.
OR, you need to redefine static, which personally, I think would be a
bad solution
Will
--
Will\,n 'wil
1. The Power of choosing
2. Power to control
3. The choice or determination of one who has authority
4. Strong wish
--
Jim
This message was posted using plain text only. Any hyperlinks you may
see were added by other parties without my permission.
I do not endorse any products or services that may be hyperlinked to
this message.
'static' simply means that the function does not have an implicit 'this'
pointer. This is only important *in the body* of the static function.
'virtual' means that the function will be dynamically bound. This is
important *at the point of call*.
The 'this' pointer is used to determine *which* function will be called.
Once you have determined that, then it's simply a matter of determining
whether or not to pass 'this' as a hidden argument to the member
function: If it's a static member function, it doesn't get a this
pointer; if it's non-static, it gets a this pointer.
On some implementations, you wouldn't even have to add code to make that
decision. MSVC, for example, passes 'this' in the ECX register. Inside a
static member function, the register contents would be ignored.
Therefore, at the point of call, the compiler could always put 'this' in
the ECX register and not have to worry about whether or not the function
is static, if it's a virtual function.
> That's not to say I can't see the point in what you're arguing for. I
> can. But I, like many others, was confused by your choice of the term
> static virtual.
I suspect it's a result of what you've been taught.
Once you learn to think outside the box, then it makes a lot of sense.
Don't think of "static member functions" as "statically bound" member
functions, but rather think of them as "member functions with no 'this'
pointer". Once you make that distinction, it becomes easier to
understand.
> Members defined as you do are not static because they make use of
> instance data, albeit only some of the time.
Ah, but you see that's the point - there are virtual functions that
never *use* the 'this' pointer inside the body of the function. Why
force the overhead of passing the this pointer to a function that, for
all intents and purposes, is static, but just happens to be bound at
runtime?
> What is needed is some new specification that doesn't carry confusing
> (to this point) baggage like static does. After all, and lets be
> honnest here, static has too many meanings already.
I won't argue that point!
The important thing to remember, though, is that allowing "static
virtual" does not change the meaning of the word static or of the word
"virtual". A static member function is one that does not have a 'this'
pointer. A virtual member function is one whose binding is determined at
runtime. The two concepts are completely compatible with each other.
Not true. Static methods may be called on instances, the only
difference is that the "this" pointer is not passed (i.e. within the
method you have no access to an implicit instance pointer). Virtual
methods rely on an instance to achieve dynamic dispatch based upon the
type at run time, but often the call can be chosen at compile time
based upon static type information. A "static virtual" receives
no "this" pointer just like a static method, can be called with out an
instance, and when called with an instance performs dynamic dispatch
based upon the type at run time.
The terms are not mutually exclusive and other OO languages permit just
such a concept.
> That's not to say I can't see the point in what you're arguing for. I
> can. But I, like many others, was confused by your choice of the term
> static virtual.
It's the only term that's valid with out extending the language by
introduction of new key words, which is not appropriate when "static
virtual" conveys the concept completely and unambiguously.
BTW, I was not the OP that started this thread. You seem to think that
I was. I've only argued with those who think it's impossible to
implement in C++, or think that it's an oxymoron.
> Members defined as you do are not static because they make use of
> instance data, albeit only some of the time.
That's a stretch on your part. "static" means what you think it means
only because C++ doesn't support a "static virtual" concept. A "static
virtual" can be called EITHER statically or
dynamically/polymorphically. The keywords are indications of allowable
call semantics, not indicators that they are the only call semantic
allowed. They simply are not mutually exclusive.
> What is needed is some new specification that doesn't carry confusing
> (to this point) baggage like static does. After all, and lets be
> honnest here, static has too many meanings already.
I agree to a point. However, static has a very well known meaning in
this context and does not lead to yet more "overloaded" meanings of the
term. Further, it is the only option available with out adding a new
key word, which is pointless and simply wouldn't be considered by the
C++ standard because of this.
You need to stop thinking about current implementations and instead
think solely about the meaning of static (as it pertains to member
function definitions).
> OR, you need to redefine static, which personally, I think would be a
> bad solution
Static does not need a new definition. The meaning of a static in this
context is "a class method which may be called with out an instance of
the class, and as such will never receive a 'this' pointer". The key
here is "may". This meaning in no way conflicts with "static virtual".
--
William E. Kempf
Software Engineer, MS Windows Programmer
#include <iostream.h>
class A
{
public:
static void f() { cout << "A's behavior" << endl ; }
} ;
class B : public A
{
public:
static void f() { cout << "B's behavior" << endl ; }
} ;
int main()
{
A* a1 = new A() ;
A* a2 = new B() ;
a1->f() ;
a2->f() ;
delete a1 ;
delete a2 ;
return 0 ;
}
gives the output:
A's behavior
A's behavior
The programmer may want a2->f() to behave according to B, since a2
points to a B. But it is trivial to get this functionality
if you want it:
class A
{
public:
virtual void f() { A::static_f() ; }
private:
static void static_f() { cout << "A's behavior" << endl ; }
} ;
class B : public A
{
public:
virtual void f() { B::static_f() ; }
private:
static void static_f() { cout << "B's behavior" << endl ; }
} ;
Using these definitions of A and B gives the output:
A's behavior
B's behavior
No need to extend the language. Here the user must call
A::static_f() (assuming I made it public) when he/she does
not have a pointer, which is clearer anyway. Naive programmers
may want to write a->static_f() in which case we are
back to square one, which is why I made it private. But
naive programmers can do just about anything, so there isn't
much defense anyway.
The defense is in maintenance of code. Seperating the two into two
seperate methods, while it works, creates an artificial liability/tie
between the two methods. It's very easy to make a modification to one
with out making an appropriate modification to the other which leads to
a broken implementation.
The fact that you can "code around" the lack of "virtual static"
methods in C++ is not an argument that they should not be considered in
the next round of standardization, IMHO. There's several others,
including comittee members, who think the same way.
--
William E. Kempf
Software Engineer, MS Windows Programmer
class T
{
public:
void f(int);
};
and you would often call it with the same value:
void g()
{
T t;
t.f(10);
}
void h()
{
T t;
t.f(10);
}
So, to save typing a people would overload f():
class T
{
public:
void f(int);
void f() { f(10); }
};
but this added maintenance overhead to the class, because now there are
two f() functions.
No need to extend the language, right? Well, Stroustrup didn't agree,
and so he invented default arguments:
class aBetterT
{
public:
void f(int i=10);
};
So, isn't allowing 'virtual static' better than having to provide two
separate functions that do the same job?
> Here the user must call
> A::static_f() (assuming I made it public) when he/she does
> not have a pointer, which is clearer anyway. Naive programmers
> may want to write a->static_f() in which case we are
> back to square one, which is why I made it private. But
> naive programmers can do just about anything, so there isn't
> much defense anyway.
a->static_f() is valid code, it just resolves (under the current rules)
statically to A::static_f(). If "virtual static" were allowed and
static_f() was declared virtual, then the binding would be delayed until
runtime.
--
Jim
This message was posted using plain text only. Any hyperlinks you may
see were added by other parties without my permission.
I do not endorse any products or services that may be hyperlinked to
this message.
Jim Hyslop <jim.h...@leitch.com> wrote in article
<8raohh$5bf$1...@nnrp1.deja.com>...
> Do I infer from this post that you have grokked the concept of static
> virtual?
>
definitions are in order:
tell me what "grokked" means and I tell you whether i've grokked it up.
:-))))
In article <8raohh$5bf$1...@nnrp1.deja.com>,
Jim Hyslop <jim.h...@leitch.com> wrote:
> a->static_f() is valid code, it just resolves (under the current
rules)
> statically to A::static_f(). If "virtual static" were allowed and
> static_f() was declared virtual, then the binding would be delayed
until
> runtime.
>
To reiterate and to answer this and sirwillard's post --- I made
static_f() private specifically to avoid the problems mentioned.
The solution is to require the user to have an object, and if
necessary to make a dummy object to call f() (or have one handy).
And yes, this is inconvienient, creates overhead, blah blah blah.
Enough already. Even if "virtual static" somehow becomes part
of the standard, it will be years and years before enough compilers
implement it to be worth my attention. Heck, the latest versions
of the compilers I use aren't even close to the standard now
(who actually implements "export"?).
In the meantime, it's the workarounds for me.
wow, "ask jeeves" sure hit the spot:
<Quote Source="http://www.sonoran-sunsets.com/dawno/grokking.html">
An extendid definition of Grok:
To achieve a intuitive sense of encounter with an idea, an understanding,
and surround it with your beingness of attention, To consume it's
perspective, and understand it all at once, to see the wholeness "of a
piece".. this is the "long wave" way of knowing, as opposed to atomized,
piecemeal, fractionated dissections of knowing.. ie, the short wave spectrum
of "knowing".
</Quote>
Rubbish.
Grok comes from Heinlein's Stranger In A Strange Land and
means "to drink". Read the book sometime...
--
<\___/>
/ O O \
\_____/ FTB.
(see my example news:vxmB5.13766$O7.1...@ozemail.com.au...)
> > (different
> > from others) can be resolved at link time.
> Do I infer from this post that you have grokked the concept of static
> virtual?
I sure have Jim.
Are you with me? Give me a sign!
--
Jim
This message was posted using plain text only. Any hyperlinks you may
see were added by other parties without my permission.
I do not endorse any products or services that may be hyperlinked to
this message.
Remember, OO means "object oriented", not "objects only" :=)
--
Jim
This message was posted using plain text only. Any hyperlinks you may
see were added by other parties without my permission.
I do not endorse any products or services that may be hyperlinked to
this message.
It does, don't worry. The idea is that if you drink something, then you
fully encompass it and it becomes part of you, which relates to the
"understanding" connotation of the way the word is used today.
I won't even dignify your judgemental, curt, egotistical post
by responding to it.
oh wait I just did.
In article <8rcls0$lba$1...@nnrp1.deja.com>,
Jim Hyslop <jim.h...@leitch.com> wrote:
> In article <8rbjqv$sco$1...@nnrp1.deja.com>,
> banan...@my-deja.com wrote:
> >
> >
> Ah, I see. You have obviously made up your mind, and it is quite clear
> that you are not open to new ideas.
>
> --
> Jim
> This message was posted using plain text only. Any hyperlinks you may
> see were added by other parties without my permission.
> I do not endorse any products or services that may be hyperlinked to
> this message.
>
It wasn't judgemental (at least not in a harsh manner as you seem to
think) or egotistical. Further, while short I wouldn't call it curt
either, as that suggests further negative connotations that I really
don't think Mr. Hyslop intended.
The fact is, he was right. You're posts indicate that you don't care
about enhancements to C++, as "they'll be years away". Makes me wonder
why you posted on this thread. It couldn't have even been to post
the "work around" for the "deficiency" in the language, because that
was already posted.
Nothing wrong with your not being interested in the change, but Mr.
Hyslop's realization that this is where you were coming from was quite
a valid realization. One that could benefit others in this thread.
> oh wait I just did.
Yes, you did.
--
William E. Kempf
Software Engineer, MS Windows Programmer
<snip>
> > You said something similar in response to one of my posts as well. I
> > think the problem a lot of people are having is that static and
> > virtual _are_ mutually exclusive. Static functions execute completely
> > independantly of any instance data, whereas virtual functions rely on
> > it intrinsicaly.
>
> Not true. Static methods may be called on instances, the only
> difference is that the "this" pointer is not passed (i.e. within the
> method you have no access to an implicit instance pointer). Virtual
> methods rely on an instance to achieve dynamic dispatch based upon the
> type at run time, but often the call can be chosen at compile time
> based upon static type information. A "static virtual" receives
> no "this" pointer just like a static method, can be called with out an
> instance, and when called with an instance performs dynamic dispatch
> based upon the type at run time.
Well... if you aren't right. Damn! I hate being wrong. :) OK... so
I've (finally you might say) checked the c++ spec, and I have to
concede. There's no mention of my suggested meaning of static
anywhere. Of course it's implied by the current meaning of the term,
but that's not binding at all. The only caveat I can think of is that
it's a good deal easier to learn that 'static means independant of
instance' than it would otherwise be, so in that sense I still think
'static virtual' would muddy the water a bit.
> It's the only term that's valid with out extending the language by
> introduction of new key words, which is not appropriate when "static
> virtual" conveys the concept completely and unambiguously.
Absolutely. I was under the impression that we were looking at a
change in meaning for static...
> BTW, I was not the OP that started this thread. You seem to think that
> I was. I've only argued with those who think it's impossible to
> implement in C++, or think that it's an oxymoron.
Not at all. I fell into the last category there, but I was just using
your posts as a response point to the thread as a whole.
> You need to stop thinking about current implementations and instead
> think solely about the meaning of static (as it pertains to member
> function definitions).
I think this is where I went wrong...
Assuming that convention defined the term.
I think I've covered most of Jim's points as well... except to say I
was never under the impression that it would be hard to implement...
'Independant of instance' is vague. Taken by itself it still applies
to static even when you have "virtual static" methods. After all,
the 'this' pointer is never passed to a static method (even if it's
a "virtual static" in our hypothetical extension to the language).
Within the method you have no (implicit) access to an instance of the
class. The tricky/confusing part is that a static method *can* be
called through an instance (it's just not passed implicitly) and
a "virtual static" would alter the way in which such a call is resolved.
> > It's the only term that's valid with out extending the language by
> > introduction of new key words, which is not appropriate when "static
> > virtual" conveys the concept completely and unambiguously.
>
> Absolutely. I was under the impression that we were looking at a
> change in meaning for static...
*chuckles* Definately not. There's too many meanings as things are
today. I would never advocate yet another meaning. Nor would any
other sane person.
> > BTW, I was not the OP that started this thread. You seem to think
that
> > I was. I've only argued with those who think it's impossible to
> > implement in C++, or think that it's an oxymoron.
>
> Not at all. I fell into the last category there, but I was just using
> your posts as a response point to the thread as a whole.
Sorry. Something said seemed to indicate that you though I was the
originator. I just wanted to make sure this wasn't the case.
> > You need to stop thinking about current implementations and instead
> > think solely about the meaning of static (as it pertains to member
> > function definitions).
>
> I think this is where I went wrong...
> Assuming that convention defined the term.
>
> I think I've covered most of Jim's points as well... except to say I
> was never under the impression that it would be hard to implement...
That was another misunderstanding. Other's in this thread claimed it
would be hard (even impossible) to implement. That's why I put both
categories in my comment, but I should have been explicit about which I
thought you fell into.