Re: How to do "derived" type extensions?
On Jan 8, 8:17 am, Kira Yamato <kira...@earthlink.net> wrote:
Suppose class B is a subtype of class A, i.e.,
class B : public A
{
...
};
Then, in C++, a pointer to type B can be treated as a pointer to type
A. So, I can do the following:
B *b;
A *a = b;
This morphism of types is what makes C++ so powerful.
What perhaps needs to be noted is that an instance of type B is_an
instance of type A.
Its not correct to say that a pointer to a B 'can be treated' as a
ponter to an A.
Now, ask yourself what makes polymorphism work?
But now how do I do the following kind of morphism? Suppose I have functions
void foo(const B &);
and
void bar(const A &);
I like to be able to declare a function pointer
void (*fp)(const B&);
and make "polymorphic" assignments like
p = foo; // this is ok in C++.
p = bar; // semantically this make sense, but C++ syntax won't
allow this!
Of course it doesn't. If it did we'ld all play russian roulette.
I know the last line of code is not valid C++ because the function
signatures are required to be the same.
However, on a semantic level,
I should be allowed to substitute calls to foo with calls to bar. This
is what I mean:
B b;
foo(b); // I can substitute the function foo in this line to
bar(b); // the function bar in this line.
Yes, absolutely, its not 'should' - you definitely can and do.
So, at least on a semantic level I should be able to declare a
"polymorphic" function pointer that can points to both foo and bar
types.
void (*fp)(const B&) = bar;
fp(b); // here, b is passed as type A to fp since bar accepts
type A argument.
But I can't, because C++ doesn't work this way.
Thankfully so. You are expecting a pointer to a function with a given
signature to accept a function signature of another type. How do you
expect a call for one signature to induce a call to anything viable?
Are you seriously suggesting that a program should silently construct
an instance of B in order to accept a reference to a base class? Thats
ludicrous and insane.
Basicly, the solution is to declare
void (*fp)(const A&);
the parameter of function at the pointer can be any_kind_of_A.
#include <iostream>
#include <typeinfo>
class A
{
public:
virtual ~A() { } // <---- polymorphism
};
class B : public A { };
class C : public B { };
void bar(const A& a)
{
std::cout << typeid(a).name() << std::endl;
}
void foo(const B& b)
{
std::cout << typeid(b).name() << std::endl;
}
int main()
{
void (*fp)(const A&);
fp = &bar;
A a;
fp(a);
B b;
fp(b); // <- b is passed as a B, see output below
C c;
fp(c);
void (*fp_b)(const B&);
fp_b = &foo;
fp_b(b);
// fp_b(a); // error:
// invalid initialization of reference
// of type 'const B&' from expression
// of type A
}
/*
A
B // <- whats this !
C
B
*/
Read the error again. Do you understand the implications if the
program was allowed to generate an instance of B silently?
Now, I know the mantra "When in Rome, do as Romans." So, if this is
not a feature of C++, then I should rework a solution that is in C++.
But I'm just curious if anyone has a "good hack" to simulate this type
of polymorphism in C++?
Sorry, hacking is not programming.