Re: Type "assurance" of derived classes
On Aug 14, 8:03 pm, Erik Wikstr=F6m <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.
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./
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.
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.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34