overloading

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Torsten Curdt

    overloading

    Let's assume I have a base class

    class X
    {
    };

    and the the following classes inheriting

    class BX : public X
    {
    };

    class AX : public X
    {
    };

    and this class

    class MyClass
    {
    void DoSomething( AX* );
    void DoSomething( BX* );
    }

    and this code

    X* = ...
    MyClass c;
    c.DoSomething(X )

    Do I have to use a reinterpret cast to
    make this work? Isn't this a runtime
    issue?
    --
    Torsten

  • Marc Schellens

    #2
    Re: overloading



    Torsten Curdt wrote:[color=blue]
    > Let's assume I have a base class
    >
    > class X
    > {
    > };
    >
    > and the the following classes inheriting
    >
    > class BX : public X
    > {
    > };
    >
    > class AX : public X
    > {
    > };
    >
    > and this class
    >
    > class MyClass
    > {
    > void DoSomething( AX* );
    > void DoSomething( BX* );
    > }
    >
    > and this code
    >
    > X* = ...
    > MyClass c;
    > c.DoSomething(X )
    >
    > Do I have to use a reinterpret cast to
    > make this work? Isn't this a runtime
    > issue?[/color]

    I guess you meant something like:

    X* XX = ...
    MyClass c;
    c.DoSomething(X X);

    You will get an error message that c.DoSomething( X*)
    is not defined.
    You need a dynamic_cast here.
    Would be dangerous if it would be a runtime issue.
    What should be done, if XX is actually of type X?

    marc

    Comment

    • Torsten Curdt

      #3
      Re: overloading

      >>Let's assume I have a base class[color=blue][color=green]
      >>
      >> class X
      >> {
      >> };
      >>
      >>and the the following classes inheriting
      >>
      >> class BX : public X
      >> {
      >> };
      >>
      >> class AX : public X
      >> {
      >> };
      >>
      >>and this class
      >>
      >> class MyClass
      >> {
      >> void DoSomething( AX* );
      >> void DoSomething( BX* );
      >> }
      >>
      >>and this code
      >>
      >> X* = ...[/color][/color]

      sure, I meant

      X* x = ...
      [color=blue][color=green]
      >> MyClass c;
      >> c.DoSomething(X )[/color][/color]

      c.DoSomething(x )
      [color=blue][color=green]
      >>
      >>Do I have to use a reinterpret cast to
      >>make this work?[/color]
      >
      >
      > Or dynamic_cast, which I would prefer.[/color]

      ok
      [color=blue][color=green]
      >>Isn't this a runtime
      >>issue?[/color]
      >
      >
      > No. X* and AX*/BX* are unrelated, since X has no direct link with
      > them. The contrary would be ok, since AX/BX inherit from X.[/color]

      Not a runtime issue? ...but think of the following:

      there is another class

      class CX : public X
      {
      };

      X* x = new CX();
      MyClass c;
      c.DoSomething(x )

      this will not work and can only be resolved at runtime because
      MyClass doesn't have a "DoSomething(CX *)", right?
      [color=blue]
      > Downcasts cannot be made implicitly, so static_cast won't work. If
      > you add a virtual dtor to X (which I hope it has in your code, else[/color]

      What do you mean by "dtor"?
      [color=blue]
      > it's undefined behavior), you can dynamic_cast `x` to `AX` or `BX`.
      > Or you can simply do a reinterpret_cas t.[/color]

      Hm.. ok
      [color=blue]
      > But this is not a good idea. If you have two different functions
      > taking AX and BX as arguments, it means they probably do something
      > different (or else you could just have one taking a X*). Now, to what
      > type would you cast X to ?
      >
      > I think this is a flawed design. What exactly are you attempting ?[/color]

      I have a list of object of type X. X is an abstract class so the objects
      in this list are actually of type AX, BX or CX. Now I am trying to
      serialize and deserialize them.

      Serialize - no problem. X has a "Serialize" function and we are done.
      But for deserialization I need to check what exact type of object I
      need to create. Since RTTI is not available I thought about this

      class ObjectFactory
      {
      static Object* NewInstance( DWORD guid );
      DWORD GetGUID( AX* o );
      DWORD GetGUID( BX* o );
      DWORD GetGUID( CX* o );
      }

      So the overloading would help me to keep the GUID mapping in one
      class. Having the "GetGUID" in each class would be a mess since
      I need to assign them by hand :-/

      What I really would need is to have the classname in each class
      automagically - but I guess that's what RTTI is about :-/

      ....or at least the filename without the full path would be nice.
      Unfortunately __FILE__ gives me the full path :-/

      Any other ideas?
      --
      Torsten

      Comment

      • Jonathan Mcdougall

        #4
        Re: overloading

        On Thu, 31 Jul 2003 18:30:57 +0200, Torsten Curdt
        <tcurdt-REMOVE@web.de> wrote:
        [color=blue][color=green][color=darkred]
        >>>Let's assume I have a base class
        >>>
        >>> class X
        >>> {
        >>> };
        >>>
        >>>and the the following classes inheriting
        >>>
        >>> class BX : public X
        >>> {
        >>> };
        >>>
        >>> class AX : public X
        >>> {
        >>> };
        >>>
        >>>and this class
        >>>
        >>> class MyClass
        >>> {
        >>> void DoSomething( AX* );
        >>> void DoSomething( BX* );
        >>> }
        >>>
        >>>and this code
        >>>
        >>> X* = ...[/color][/color]
        >
        >sure, I meant
        >
        > X* x = ...
        >[color=green][color=darkred]
        >>> MyClass c;
        >>> c.DoSomething(X )[/color][/color]
        >
        > c.DoSomething(x )
        >[color=green][color=darkred]
        >>>
        >>>Do I have to use a reinterpret cast to
        >>>make this work?[/color]
        >>
        >>
        >> Or dynamic_cast, which I would prefer.[/color]
        >
        >ok
        >[color=green][color=darkred]
        >>>Isn't this a runtime
        >>>issue?[/color]
        >>
        >>
        >> No. X* and AX*/BX* are unrelated, since X has no direct link with
        >> them. The contrary would be ok, since AX/BX inherit from X.[/color]
        >
        >Not a runtime issue? ...but think of the following:
        >
        >there is another class
        >
        > class CX : public X
        > {
        > };
        >
        > X* x = new CX();
        > MyClass c;
        > c.DoSomething(x )[/color]

        This does not compiler neither. The _static_ type of 'x' is X* and
        this cannot be converted implicitly to AX* or BX*. The _dynamic_ (or
        runtime) type of 'x' is 'CX', but the compiler does not know that, the
        runtime system does. So the compiler is only trying to convert X* to
        AX* or BX* and it simply cannot. That's the same thing as converting
        a MyClass to a UnrelatedOtherC lass.
        [color=blue]
        >this will not work and can only be resolved at runtime because
        >MyClass doesn't have a "DoSomething(CX *)", right?
        >[color=green]
        >> Downcasts cannot be made implicitly, so static_cast won't work. If
        >> you add a virtual dtor to X (which I hope it has in your code, else[/color]
        >
        >What do you mean by "dtor"?[/color]

        destructor, sorry.
        [color=blue][color=green]
        >> But this is not a good idea. If you have two different functions
        >> taking AX and BX as arguments, it means they probably do something
        >> different (or else you could just have one taking a X*). Now, to what
        >> type would you cast X to ?
        >>
        >> I think this is a flawed design. What exactly are you attempting ?[/color]
        >
        >I have a list of object of type X. X is an abstract class so the objects
        >in this list are actually of type AX, BX or CX. Now I am trying to
        >serialize and deserialize them.
        >
        >Serialize - no problem. X has a "Serialize" function and we are done.
        >But for deserialization I need to check what exact type of object I
        >need to create. Since RTTI is not available I thought about this
        >
        >class ObjectFactory
        >{
        > static Object* NewInstance( DWORD guid );
        > DWORD GetGUID( AX* o );
        > DWORD GetGUID( BX* o );
        > DWORD GetGUID( CX* o );
        >}
        >
        >So the overloading would help me to keep the GUID mapping in one
        >class. Having the "GetGUID" in each class would be a mess since
        >I need to assign them by hand :-/
        >
        >What I really would need is to have the classname in each class
        >automagicall y - but I guess that's what RTTI is about :-/
        >
        >...or at least the filename without the full path would be nice.
        >Unfortunatel y __FILE__ gives me the full path :-/[/color]

        Something like that ?

        class X
        {
        public:
        void serialize();
        virtual ~X();

        // pure virtual, child must implement it
        void deserialize() = 0;
        };

        class AX : public X
        {
        public:
        void deserialize()
        {
        /* .. */
        }
        };

        class BX : public X
        {
        public:
        void deserialize()
        {
        /* .. */
        }
        };

        int main()
        {
        X *x = new BX;

        // calls X::serialize
        // call resolved at compile time
        x->serialize();

        // calls BX::deserialize ()
        // call resolved at runtime
        x->deserialize( );
        }


        Jonathan

        Comment

        • Torsten Curdt

          #5
          Re: overloading

          >>I have a list of object of type X. X is an abstract class so the objects[color=blue][color=green]
          >>in this list are actually of type AX, BX or CX. Now I am trying to
          >>serialize and deserialize them.
          >>
          >>Serialize - no problem. X has a "Serialize" function and we are done.
          >>But for deserialization I need to check what exact type of object I
          >>need to create. Since RTTI is not available[/color]
          >
          >
          > Why is it not available?[/color]

          I am using eVC++ 4.0 and there is no such setting.
          The help states something about a compiler switch
          which I *maybe* could add by hand. Haven't tried yet
          though.

          Anyway I would prefer to use a pattern.
          I need the same serialization/deserialization
          in other languages (namely php), too. I'd prefer
          to use the same mechanism.
          [color=blue][color=green]
          >>I thought about this
          >>
          >>class ObjectFactory
          >>{
          >> static Object* NewInstance( DWORD guid );
          >> DWORD GetGUID( AX* o );
          >> DWORD GetGUID( BX* o );
          >> DWORD GetGUID( CX* o );[/color]
          >
          >
          > Those three could also be 'static', no?[/color]

          Yes
          [color=blue]
          > What in your deserialisation code controls what object is created?
          > Is there some kind of code or value that, when read from the stream,
          > tells you what object to create?[/color]

          Exactly
          [color=blue]
          > Is GUID your "code"? If you read
          > a GUID from the stream, why do you need those GetGUID() functions?[/color]

          They are for used on serialization.
          [color=blue]
          > How does 'NewInstance' use the 'GetGUID'? Does it? It seems that
          > 'GetGUID' is only needed during serialisation part, not de-...[/color]

          Exactly

          On serialializatio n the "GetGUID" is used to get the right id into
          the stream. On deserialization the id is taken as input for the
          factory.
          --
          Torsten

          Comment

          • Torsten Curdt

            #6
            Re: overloading

            > This does not compiler neither. The _static_ type of 'x' is X* and[color=blue]
            > this cannot be converted implicitly to AX* or BX*. The _dynamic_ (or
            > runtime) type of 'x' is 'CX', but the compiler does not know that, the
            > runtime system does. So the compiler is only trying to convert X* to
            > AX* or BX* and it simply cannot. That's the same thing as converting
            > a MyClass to a UnrelatedOtherC lass.[/color]

            Hm... couldn't I tell the compiler that this should be resolved
            at runtime?

            <snip/>
            [color=blue]
            > Something like that ?
            >
            > class X
            > {
            > public:
            > void serialize();
            > virtual ~X();
            >
            > // pure virtual, child must implement it
            > void deserialize() = 0;
            > };[/color]

            <snip/>

            That doesn't help because the information of which
            object needs to be created comes from the stream.
            So I need a factory that knows about

            Classname = GUID
            AX = 1
            BX = 2
            CX = 3
            Whateverclass = 4

            So it can create the appropriate object on runtime.
            The GUID -> class is done in the factory. But for
            not messing up with the ids I also should ask the
            factory for class -> GUID.

            Even if I register the classes to the factory

            Factory::Regist er("AX",1);
            Factory::Regist er("BX",2);
            Factory::Regist er("CX",3);

            I need to get the textual representation of
            the object on serialization.

            AX* a = new AX();
            a -?-> "AX"

            Only way I see up to now is having a virtual
            "GetClassname() " function in each object
            returning the classname.
            --
            Torsten

            Comment

            Working...