 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
gvv Guest
|
Posted: Sat Mar 19, 2005 12:13 am Post subject: inheritance, dynamic_cast and templates |
|
|
Two Questions.
1) What is the theoretical explanation to the code below
GetMyName(d2->GetSuperClass()) returning BASE instead of DERIVE1.
2) Given the code below is there a pragmatic way to ascend the inheritance
heirarchy in a recursive function without said function defined as a
template.
class Base
{
public:
Base() {}
virtual ~Base() {}
string GetName() const
{
return "BASE";
}
virtual Base* GetSuperClass()
{return NULL;}
};
class Derive1 : public Base
{
public:
Derive1() {}
string GetName() const
{
return "DERIVE1";
}
virtual Base* GetSuperClass()
{return dynamic_cast<Base*>(this);}
};
class Derive2 : public Derive1
{
public:
Derive2() {}
string GetName() const
{
return "DERIVE2";
}
virtual Derive1* GetSuperClass()
{return dynamic_cast<Derive1*>(this) ;}
};
string GetMyName(Base* obj)
{
return obj->GetName();
}
template<typename T>
string GetMyNameT(T* obj)
{
return obj->GetName();
}
int main()
{
Derive2* d2 = new Derive2;
cout << d2->GetSuperClass()->GetName() << endl; // DERIVE1
cout << d2->GetSuperClass()->GetSuperClass()->GetName() << endl; // BASE
cout << GetMyName(d2->GetSuperClass()) << endl; // BASE
cout << GetMyNameT(d2->GetSuperClass()) << endl; // DERIVE1
delete d2;
return 0;
}
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
R Samuel Klatchko Guest
|
Posted: Sat Mar 19, 2005 10:41 am Post subject: Re: inheritance, dynamic_cast and templates |
|
|
gvv wrote:
| Quote: | Two Questions.
1) What is the theoretical explanation to the code below
GetMyName(d2->GetSuperClass()) returning BASE instead of DERIVE1.
class Base
{
public:
Base() {}
virtual ~Base() {}
string GetName() const
{
return "BASE";
}
virtual Base* GetSuperClass()
{return NULL;}
};
string GetMyName(Base* obj)
{
return obj->GetName();
}
|
GetMyName() takes a point to a Base* and the method GetName() is not
virtual. Therefore it will always call Base::GetName(). The fact that
Base* actually points to a Derived is irrelevant when the method you
call is not virtual.
samuel
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Carl Barron Guest
|
Posted: Sat Mar 19, 2005 10:45 am Post subject: Re: inheritance, dynamic_cast and templates |
|
|
gvv <gvv (AT) swiftdsl (DOT) com.au> wrote:
| Quote: | Two Questions.
1) What is the theoretical explanation to the code below
GetMyName(d2->GetSuperClass()) returning BASE instead of DERIVE1.
2) Given the code below is there a pragmatic way to ascend the inheritance
heirarchy in a recursive function without said function defined as a
template.
class Base
{
[SNIP]
string GetMyName(Base* obj)
{
return obj->GetName();
}
template<typename T
string GetMyNameT(T* obj)
{
return obj->GetName();
}
int main()
{
Derive2* d2 = new Derive2;
cout << d2->GetSuperClass()->GetName() << endl; // DERIVE1
cout << d2->GetSuperClass()->GetSuperClass()->GetName() << endl; // BASE
cout << GetMyName(d2->GetSuperClass()) << endl; // BASE
cout << GetMyNameT(d2->GetSuperClass()) << endl; // DERIVE1
delete d2;
return 0;
}
GetNyName(Base *); is an ordinary functon and GetMyNameT is a |
template, in short that is why the different behavior.
There is no function GetMyName(Derived1*) or GetMyName(Derived2 *) but
there is one GetMyName(Base *) and conversionto base pointer is in the
process of candidates for overloading thus the function with a Base * is
chosen. Now the method GetName() is not virtual so that the method of
the base class will be used for any class derived publically from Base
with the current code, if you want the 'proper' code for the method
GetName() to be used, the function should be virtual.
Now on to GetNameT
the candidate list of overloads is GetMyNameT<T>(T *) so it choses the
'proper' overload and prints the name of the derived class. There are
tricks to get this to return the Base result using boost::enable_if or
equivalent, and some type traits to determine if T is derived from Bass.
something like:
template <class T>
struct is_a_Base :boost::enable_if
<
is_convertable
Base
template <class T>
std::string GetMyNameT( typename is_a_Base<T>::type *obj)
{
return obj->GetName();
}
will convert to a Derived1 * [or a Derived2 *] to a Base * if that is
what you want via templates.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Thomas Maeder Guest
|
Posted: Sat Mar 19, 2005 10:46 am Post subject: Re: inheritance, dynamic_cast and templates |
|
|
[email]gvv (AT) swiftdsl (DOT) com.au[/email] (gvv) writes:
| Quote: | Two Questions.
1) What is the theoretical explanation to the code below
GetMyName(d2->GetSuperClass()) returning BASE instead of DERIVE1.
|
The argument to GetMyName is a Base *. How could calling anything but
Base::GetName() even be considered?
| Quote: | 2) Given the code below is there a pragmatic way to ascend the inheritance
heirarchy in a recursive function without said function defined as a
template.
|
I don't understand the problem that you are trying to solve.
| Quote: | class Derive1 : public Base
{
public:
Derive1() {}
string GetName() const
{
return "DERIVE1";
}
virtual Base* GetSuperClass()
{return dynamic_cast<Base*>(this);}
|
Why not simply
return this;
?
| Quote: | };
class Derive2 : public Derive1
{
public:
Derive2() {}
string GetName() const
{
return "DERIVE2";
}
virtual Derive1* GetSuperClass()
{return dynamic_cast<Derive1*>(this) ;}
|
Ditto.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Llewelly Guest
|
Posted: Sun Mar 20, 2005 9:04 am Post subject: Re: inheritance, dynamic_cast and templates |
|
|
[email]gvv (AT) swiftdsl (DOT) com.au[/email] (gvv) writes:
| Quote: | Two Questions.
1) What is the theoretical explanation to the code below
GetMyName(d2->GetSuperClass()) returning BASE instead of DERIVE1.
2) Given the code below is there a pragmatic way to ascend the inheritance
heirarchy in a recursive function without said function defined as a
template.
class Base
{
public:
Base() {}
virtual ~Base() {}
string GetName() const
|
GetName() is not virtual. Therefor, when GetName() is called, the
static type of the object will used to determein which GetName()
is selected.
| Quote: | {
return "BASE";
}
virtual Base* GetSuperClass()
{return NULL;}
};
class Derive1 : public Base
{
public:
Derive1() {}
string GetName() const
{
return "DERIVE1";
}
virtual Base* GetSuperClass()
{return dynamic_cast<Base*>(this);}
};
class Derive2 : public Derive1
{
public:
Derive2() {}
string GetName() const
{
return "DERIVE2";
}
virtual Derive1* GetSuperClass()
{return dynamic_cast<Derive1*>(this) ;}
};
string GetMyName(Base* obj)
{
return obj->GetName();
|
The static type of obj is Base*. So Base::GetName() is called.
| Quote: | }
template<typename T
string GetMyNameT(T* obj)
{
return obj->GetName();
|
Here the static type of obj is T*. So T::GetName() is called. Iff T is
Derive1 then Derive1::GetName() is called.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|