Isn't this a polymorphic call?

A

Arindam

#include <cstdio>

struct Test {
void bar() {
foo();
}
private:
virtual void foo() {
printf("Test\n");
}
};

struct Test2 : public Test {
void foo() {
printf("Test2\n");
}
};

int main(int argc, char* argv[])
{
Test2 v;
v.bar();
}

Does the call to v.bar() amount to a polymorphic invocation of foo()?
If not, I am guessing the following will be polymorphic:

int main(int argc, char* argv[])
{
Test2 v;
Test * pv = &v;
pv->bar();
}

bar takes a _this_ pointer whose static type is Test*. Therefore I am
reasoning that v.bar is something like:

bar(Test* this) being invoked as:

Test2 v;
bar(&v);

But inside bar, the static type of _this_ is really Test*. But
invoking foo() on it will resolve to Test2::foo. So both should be
polymorphic. Ami I correct?

Cheers,
Arindam
 
A

Arindam

Arindam said:
#include <cstdio>
struct Test {
void bar() {
foo();
}
private:
virtual void foo() {
printf("Test\n");
}
};
struct Test2 : public Test {
void foo() {
printf("Test2\n");
}
};
int main(int argc, char* argv[])
{
Test2 v;
v.bar();
}
Does the call to v.bar() amount to a polymorphic invocation of foo()?

Have you tried it?  If you have, what happened?  If not, why not?

Yes - it prints Test2. So this should be polymorphic right?
If not, I am guessing the following will be polymorphic:
int main(int argc, char* argv[])
{
Test2 v;
Test * pv = &v;
pv->bar();
}
bar takes a _this_ pointer whose static type is Test*. Therefore I am
reasoning that v.bar is something like:
bar(Test* this) being invoked as:
Test2 v;
bar(&v);
But inside bar, the static type of _this_ is really Test*. But
invoking foo() on it will resolve to Test2::foo. So both should be
polymorphic. Ami I correct?

I think so.

The same result here.
 
J

James Kanze

Arindam wrote:
#include <cstdio>
struct Test {
void bar() {
foo();
}
private:
virtual void foo() {
printf("Test\n");
}
};
struct Test2 : public Test {
void foo() {
printf("Test2\n");
}
};
int main(int argc, char* argv[])
{
Test2 v;
v.bar();
}
Does the call to v.bar() amount to a polymorphic
invocation of foo()?
Have you tried it? If you have, what happened? If not, why not?
Yes - it prints Test2. So this should be polymorphic right?
It is not polymorphic according to the inventor of C++, who
wrote in "The C++ Programming Language (Third Edition)":
"To get polymorphic behavior in C++, the member functions called must
be virtual and objects must be manipulated through pointers or
references. When manipulating an object directly (rather than through
a pointer or reference), its exact type is known by the compiler so
that run-time polymorphism is not needed."

And? He's calling foo() through a pointer (this), and the call
is resolved polymorphicly.
 
A

Arindam

Arindam wrote:
#include <cstdio>
struct Test {
void bar() {
foo();
}
private:
virtual void foo() {
printf("Test\n");
}
};
struct Test2 : public Test {
void foo() {
printf("Test2\n");
}
};
int main(int argc, char* argv[])
{
Test2 v;
v.bar();
}


It is not polymorphic according to the inventor of C++, who wrote in
"The C++ Programming Language (Third Edition)":

"To get polymorphic behavior in C++, the member functions called must
be virtual and objects must be manipulated through pointers or
references.  When manipulating an object directly (rather than through
a pointer or reference), its exact type is known by the compiler so
that run-time polymorphism is not needed."- Hide quoted text -

As Victor Bazarov suggested, removing the "virtual" keyword is a crisp
test. If you remove it, you will see "Test" being printed instead of
Test2.
 
J

James Kanze

* James Kanze:
Arindam wrote:
#include <cstdio>
struct Test {
void bar() {
foo();
}
private:
virtual void foo() {
printf("Test\n");
}
};
struct Test2 : public Test {
void foo() {
printf("Test2\n");
}
};
int main(int argc, char* argv[])
{
Test2 v;
v.bar();
}
Does the call to v.bar() amount to a polymorphic
invocation of foo()?
Have you tried it? If you have, what happened? If not, why not?
Yes - it prints Test2. So this should be polymorphic right?
It is not polymorphic according to the inventor of C++, who
wrote in "The C++ Programming Language (Third Edition)":
"To get polymorphic behavior in C++, the member functions
called must be virtual and objects must be manipulated
through pointers or references. When manipulating an
object directly (rather than through a pointer or
reference), its exact type is known by the compiler so that
run-time polymorphism is not needed."
And? He's calling foo() through a pointer (this), and the
call is resolved polymorphicly.
I think the question is (nearly) meaningless. The standard
doesn't guarantee how any call is resolved at the machine code
level. E.g. in this case the compiler may inline everything
so that there's no call instruction.

I almost answered like that myself. The real question is: what
does he mean by polymorphic behavior. In the end, whatever code
the compiler generates, however, the call must resolve to the
dynamic type, and not the static type, because the function is
virtual. How the compiler ensures this is its business.

And that, IMHO, is the real definition of polymorphism; the
behavior corresponds to that of the dynamic type of the object.
(Of course, we both agree that if the compiler can determine
what the dynamic type will be, then it can generate different,
and typically more efficient, code than if it can't.)
 

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,774
Messages
2,569,599
Members
45,173
Latest member
GeraldReund
Top