Re: Type "assurance" of derived classes
James Kanze wrote:
On Aug 14, 8:03 pm, Erik Wikstr?m <Erik-wikst...@telia.com> wrote:
On 2008-08-14 12:44, Pascal J. Bourguignon wrote:
Oliver Graeser <grae...@phy.cuhk.edu.hk> writes:
I'm coming from Java to C++ and this is one of the very
last problems I have so far... In Java, if I have, say, a
class SISNode that extends NetworkNode, I can have a
function that returns a NetworkNode but I can assure the
compiler that it is in fact a SISNode and therefore call
the method getStatus() that only a SISNode has. Like
SISnode s,t;
NetworkNode n;
n =t;
n.getStatus();//won't work
s= (SISNode) n;
s.getStatus(); //will work
This is supposed to be Java, I suppose.
Yes, it was supposed to be Java
The exact equivalent in C++ would be:
SISnode* s ;
SISnode* t ;
NetworkNode* n ;
n = t ;
n->getStatus() ; // won't work
s = dynamic_cast< SISnode* >( n ) ;
s->getStatus() ; // will work./
Thanks a lot for that! I will consider what Alf Steinbach wrote above on
how to do it with a boost::shared_ptr, but in any case this is exactly
what I was trying to do. The word "dynamic_cast" is actually the key, it
is really hard to google something when you don't know its name ;)
I think his example is supposed to be Java. Otherwise, it won't
compile.
...
...
I'm now looking for some way to do this in C++. I do
agent-based network simulations, and I want to derive all
kinds of agents from a generic network node type. This
network node is supposed to store his neighbours in a
std::list<GenericNetworkNode> list. Now in the derived
classes I can obtain the neighbours, but I cannot call
their methods unless they were already declared in the
GenericNetworkNode declaration.
Anybody knows how to solve this problem? A hint in the
right direction (keyword) would be more than enough....
The two important points to remember are that C++ has value
semantics by default, you have to explicitly use pointers or
references to get reference semantics, and that the equivalent
to Java's cast operator in C++ is dynamic_cast.
This is not possible, with what you wrote above and the assumed
declarations. You must realise that when you run n=t; you lose all
the information specific to a SISNode. There is no way to build it
back.
If they above were C++, he'd not loose any type information.
But he'd get a new object (with a new type), which is probably
not what he wants.
Yup. Actually this was a problem I encountered before when I had an
object a, created a new object b, said b=a, manipulated b and was
stunned that a was still the same.... I'm sorry, I think the question
was probably not really well asked, I tried to keep it concise.
That's why I consider that C++ objects should always be
allocated dynamically and referend thru a pointer.
That's valid for entity objects, but not for value objects.
If you had written:
class SISNode:public NetworkNode {...};
SISNode* s=new SISNode();
NetworkNode* n=s;
then you could write:
SISNode* nAsSISNode=dynamic_cast<SISNode*>n;
if(nAsSISNode!=0){ nAsSISNode->getStatus(); }
And, assuming that NetworkNode is derived from
GenericNetworkNode you can then use
std::list<GenericNetworkNode*> to store them. Though it might
be worth to follow Alf's advice and use some kind of smart
pointer (which would make it
std::list<SmartPointerType<GenericNetworkNode> >).
If these are entity objects, as it would seem, I don't know of a
smart pointer that would really be appropriate.
Ayah. Smart pointer, entity objects, value objects - enough for today to
read on. Thanks a lot, everyone!
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34