C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

inheritance, dynamic_cast and templates

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
gvv
Guest





PostPosted: Sat Mar 19, 2005 12:13 am    Post subject: inheritance, dynamic_cast and templates Reply with 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
{
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





PostPosted: Sat Mar 19, 2005 10:41 am    Post subject: Re: inheritance, dynamic_cast and templates Reply with quote



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





PostPosted: Sat Mar 19, 2005 10:45 am    Post subject: Re: inheritance, dynamic_cast and templates Reply with quote



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
Quote:

{};


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





PostPosted: Sat Mar 19, 2005 10:46 am    Post subject: Re: inheritance, dynamic_cast and templates Reply with quote

[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





PostPosted: Sun Mar 20, 2005 9:04 am    Post subject: Re: inheritance, dynamic_cast and templates Reply with quote

[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.

Quote:
}
[snip]


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.