Why are there no static virtual functions?

P

Philipp

Hello
I don't exactly understand why there are no static virtual functions. I
would have liked something like this:

class Base{
static virtual std::string getName(){
return "Base";
}
}

class Derived: public Base{
static std::string getName(){
return "Derived";
}
}

so I can compare with what some pointer gives me. eg.

Base* pointer = getSomeBasePointer();
if( pointer->getName == Derived::getName() ){
doSomething();
}

Could someone please explain why this is so?
Thanks Phil
 
J

Jim Langston

Philipp said:
Hello
I don't exactly understand why there are no static virtual functions. I
would have liked something like this:

class Base{
static virtual std::string getName(){
return "Base";
}
}

class Derived: public Base{
static std::string getName(){
return "Derived";
}
}

so I can compare with what some pointer gives me. eg.

Base* pointer = getSomeBasePointer();
if( pointer->getName == Derived::getName() ){
doSomething();
}

Could someone please explain why this is so?
Thanks Phil

Why would you want to make it static? Just get rid of the static keyword,
and it does what you want.

What are you hoping to accomplish by adding the static keyword to the
method?
 
T

Thomas J. Gritzan

Philipp said:
Hello
I don't exactly understand why there are no static virtual functions. I

Because virtual functions depend on the actual object you call the function
with. But static functions don't need objects.
would have liked something like this: [...]
so I can compare with what some pointer gives me. eg.

Base* pointer = getSomeBasePointer();
if( pointer->getName == Derived::getName() ){
doSomething();
}

This can be done with typeid:

if (typeid(*pointer) == typeid(Derived))
// ...
 
P

Philipp

Thomas said:
Because virtual functions depend on the actual object you call the function
with. But static functions don't need objects.

I think of "virtual" as "gets overriden by derived classes", is this wrong?

In that sense, I was expecting that a static function could be overriden
by a derived class (ie: function is virtual _and_ static).

From your explaination I understand that this is a compiler /
optimization issue.

This can be done with typeid:

if (typeid(*pointer) == typeid(Derived))
// ...

Yes thanks (I did it with dynamic cast, same thing).

Phil
 
M

mlimber

Philipp said:
I would have liked something like this:

class Base{
static virtual std::string getName(){
return "Base";
}
}

class Derived: public Base{
static std::string getName(){
return "Derived";
}
}

so I can compare with what some pointer gives me. eg.

Base* pointer = getSomeBasePointer();
if( pointer->getName == Derived::getName() ){
doSomething();
}

Virtual functions exist to eliminate this sort of explicit type
checking in your code.

See for instance

http://www.parashift.com/c++-faq-lite/big-picture.html#faq-6.9

Cheers! --M
 
T

Tim Slattery

Philipp said:
I think of "virtual" as "gets overriden by derived classes", is this wrong?

Kind of. Non-virtual methods can be overridden also. If a method is
"virtual" then you are guaranteed that the correct method will be
called even if you access the object by a pointer to an ancestor
object and that ancestor has a different version of the method.

--
Tim Slattery
(e-mail address removed)
http://members.cox.net/slatteryt
 
R

Rolf Magnus

Philipp said:
I think of "virtual" as "gets overriden by derived classes", is this
wrong?

That's right. The override that is chosen depends on the dynamic type of the
object that you call the virtual function for. But here's the trouble. A
static member function has no object, hence no dynamic type, so there is no
way to choose which function to actually call. Example:

#include <iostream>

class Base
{
public:
virtual void test() { std::cout << "Base\n"; }
};

class Derived1 : public Base
{
public:
virtual void test() { std::cout << "Derived1\n"; }
};

class Derived2 : public Base
{
public:
virtual void test() { std::cout << "Derived2\n"; }
};

int main()
{
Base b;
Derived1 d1;
Derived2 d2;

Base* p = &b;

p->test(); // Prints "Base"
p = &d1;
p->test(); // Prints "Derived1"
p = &d2;
p->test(); // Prints "Derived2"
}

Simple inheritance. Now with static virtuals (assuming they were allowed):

#include <iostream>

class Base
{
public:
static virtual void test() { std::cout << "Base\n"; }
};

class Derived1 : public Base
{
public:
static virtual void test() { std::cout << "Derived1\n"; }
};

class Derived2 : public Base
{
public:
static virtual void test() { std::cout << "Derived2\n"; }
};

int main()
{
Base::test(); // Prints Base
Derived1::test(); // Prints Derived1
Derived2::test(); // Prints Derived2
}

Now there is nothing dynamic anymore. The function to be called is chosen
statically. So what would the virtual keyword be good for? How and why
would the compiler at runtime choose which of those three functions to
call?
In that sense, I was expecting that a static function could be overriden
by a derived class (ie: function is virtual _and_ static).

From your explaination I understand that this is a compiler /
optimization issue.

No, it's a logic issue. Having a function that is both virtual and static
makes no sense.
 
B

benben

Philipp said:
Hello
I don't exactly understand why there are no static virtual functions. I
would have liked something like this:

class Base{
static virtual std::string getName(){
return "Base";
}
}

class Derived: public Base{
static std::string getName(){
return "Derived";
}
}

so I can compare with what some pointer gives me. eg.

Base* pointer = getSomeBasePointer();
if( pointer->getName == Derived::getName() ){
doSomething();
}

Could someone please explain why this is so?
Thanks Phil

There is a logic hole in here. If you can have static virtual then you
can write:

class Base
{
public: static virtual void foo()
{
std::cout << "Base";
}
};

class Derived1: public Base
{
public: static void foo()
{
std::cout << "Derived1";
}
};

class Derived2: public Base
{
public: static void foo()
{
std::cout << "Derived2";
}
};

int main()
{
Base::foo(); // What's the output???
}

Ben
 
A

Alf P. Steinbach

* benben:
There is a logic hole in here.

You mean, in the following:

If you can have static virtual then you
can write:

class Base
{
public: static virtual void foo()
{
std::cout << "Base";
}
};

class Derived1: public Base
{
public: static void foo()
{
std::cout << "Derived1";
}
};

class Derived2: public Base
{
public: static void foo()
{
std::cout << "Derived2";
}
};

int main()
{
Base::foo(); // What's the output???
}

It depends on how the hypothetical extension of C++ is defined.

There are two possibly useful definitions of "static virtual" I know of.
One is the OP's example, where a member function doesn't access the
'this' pointer implicitly or explicitly, and so can be called
statically, but where the point is that it can also be called
dynamically (virtually). This can be emulated by having an ordinary
virtual function forward to a corresponding static member function. The
other is to have "static virtual" denote a virtual member of a class'
meta-class. I believe this is supported in the Delphi language.

For the first definition the output would be "Base", since with that
definition the function is called statically in the example above, while
with the second definition it's more unclear what the output would be:
it would depend on the syntactical rules adopted (e.g. special syntax
for accessing the metaclass object, or not).
 
P

Philipp

Alf said:
(...) where a member function doesn't access the
'this' pointer implicitly or explicitly, and so can be called
statically, but where the point is that it can also be called
dynamically (virtually). This can be emulated by having an ordinary
virtual function forward to a corresponding static member function.

Yes, thanks, on next refactoring I will do this.
Phil
 
P

Philipp

Rolf said:
That's right. The override that is chosen depends on the dynamic type of the
object that you call the virtual function for. But here's the trouble. A
static member function has no object, hence no dynamic type, so there is no
way to choose which function to actually call. Example:

#include <iostream>

class Base
{
public:
virtual void test() { std::cout << "Base\n"; }
};

class Derived1 : public Base
{
public:
virtual void test() { std::cout << "Derived1\n"; }
};

class Derived2 : public Base
{
public:
virtual void test() { std::cout << "Derived2\n"; }
};

int main()
{
Base b;
Derived1 d1;
Derived2 d2;

Base* p = &b;

p->test(); // Prints "Base"
p = &d1;
p->test(); // Prints "Derived1"
p = &d2;
p->test(); // Prints "Derived2"
}

Simple inheritance. Now with static virtuals (assuming they were allowed):

#include <iostream>

class Base
{
public:
static virtual void test() { std::cout << "Base\n"; }
};

class Derived1 : public Base
{
public:
static virtual void test() { std::cout << "Derived1\n"; }
};

class Derived2 : public Base
{
public:
static virtual void test() { std::cout << "Derived2\n"; }
};

int main()
{
Base::test(); // Prints Base
Derived1::test(); // Prints Derived1
Derived2::test(); // Prints Derived2
}


Hello and thanks for your answer.
So what would the virtual keyword be good for?

So that you get dynamic binding on pointers, but still static access
with the classes name.
How and why
would the compiler at runtime choose which of those three functions to
call?

I think you provided my expected behavior in your example.
p->test() calls the derived (dynamic) test() for p*
Base::test() calls test() statically from Base
Derived1::test() calls test() statically from Derived1

As Mr. Steinbach pointed out, this can be achieved by the virtual
function calling a static function inside the class.
No, it's a logic issue. Having a function that is both virtual and static
makes no sense.

I still think it makes sense, but as there is an easy workaround, it
won't hurt me much.

Phil
 
G

Grizlyk

Philipp said:
I still think it makes sense, but as there is an easy workaround, it
won't hurt me much.

How can you call your "static virtual" functions?
The keyword "virtual" means "use real class of real object" instead of
"use any base class of real object".

Are you going to call your "static virtual" function over pointer to
its base class without creating of object? But in the case your "static
virtual" function has no information about real class of object, has
only about class of pointer, because object is absent. You can call
only "base::foo" function, so the function can be ordinary static, not
virtual.

If you want to use already created object, you can declare your
function as ordinary virtual, not static.

If you think, that your virtual no need object after call, but C++ will
post to you hidden pointer to object, that it is compiler depended,
super-optimal compiler can generate virtuals without hidden pointers if
"this" is not used there, C++ does not deny, but not require.
 
V

Victor Bazarov

Philipp said:
Sorry, how can I view this message from the link you provide? (google
search didn't bring up anything). Thanks

Search 'comp.lang.c++.*' for "no virtual static" and/or "no static
virtual" (with double quotes). A few good threads are found that way.

V
 

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

Members online

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top