public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Polymorphism: via base pointer getting the original object
@ 2023-04-26 17:20 U.Mutlu
  2023-04-26 17:33 ` Jonathan Wakely
  2023-04-26 17:35 ` Andrew Haley
  0 siblings, 2 replies; 4+ messages in thread
From: U.Mutlu @ 2023-04-26 17:20 UTC (permalink / raw)
  To: gcc-help

Hi,
I have a base class Base_t and multiple derived classes from it (like Dog_t 
and Cat_t, and so on).
I collect the base addresses of these objects in a vector.
By using this vector I then need to access the original objects.
Not just some virtual functions of the objects, but the complete original object.
How best to do this?

The following solution is IMO not that satisfactory.

Is there a better way, maybe in newer C++ standards like c++20? Something like:
auto& X = helper(pBase);    // X will be of type Dog_t or Cat_t etc.

Thx


class Base_t { ...
class Dog_t : public Base_t { ...
class Cat_t : public Base_t { ...
...

enum Type_t { Unknown, Base, Dog, Cat };

struct Identity_t
   {
     Type_t Type;
     union
       {
         Base_t* pBase;
         Dog_t*  pDog;
         Cat_t*  pCat;
       };

     Identity_t() : Type(Unknown) { pBase = nullptr; }
   };

Identity_t Identity(Base_t* pBase)
   {
     Identity_t I;
     if ((I.pDog = dynamic_cast<Dog_t*>(pBase))) { I.Type = Dog; return I; }
     if ((I.pCat = dynamic_cast<Cat_t*>(pBase))) { I.Type = Cat; return I; }
     return I;
   }


// And using it like this:
// p is the address of a derived object, ie. Dog_t* or Cat_t*

auto I = Identity(p);
if (I.Type == Dog)
   { // use I.pDog to access it
     auto& X = *I.pDog;
     X.print();
   }
else if (I.Type == Cat)
   { // use I.pCat to access it
     auto& X = *I.pCat;
     X.print();
   }

...
// end of code


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Polymorphism: via base pointer getting the original object
  2023-04-26 17:20 Polymorphism: via base pointer getting the original object U.Mutlu
@ 2023-04-26 17:33 ` Jonathan Wakely
  2023-04-26 17:35 ` Andrew Haley
  1 sibling, 0 replies; 4+ messages in thread
From: Jonathan Wakely @ 2023-04-26 17:33 UTC (permalink / raw)
  To: U.Mutlu; +Cc: gcc-help

[-- Attachment #1: Type: text/plain, Size: 1918 bytes --]

On Wed, 26 Apr 2023, 18:21 U.Mutlu, <um@mutluit.com> wrote:

> Hi,
> I have a base class Base_t and multiple derived classes from it (like
> Dog_t
> and Cat_t, and so on).
> I collect the base addresses of these objects in a vector.
> By using this vector I then need to access the original objects.
> Not just some virtual functions of the objects, but the complete original
> object.
> How best to do this?
>
> The following solution is IMO not that satisfactory.
>
> Is there a better way, maybe in newer C++ standards like c++20? Something
> like:
> auto& X = helper(pBase);    // X will be of type Dog_t or Cat_t etc.
>

How can helper return different types?

You could make it return std::variant<Cat*, Dog*> and then use std::visit
to access the active pointer stored in it.

So something like your Identity function that returns a variant, then do:

std::visit([](auto* x){ x->print(); }, Identity(p);



> Thx
>
>
> class Base_t { ...
> class Dog_t : public Base_t { ...
> class Cat_t : public Base_t { ...
> ...
>
> enum Type_t { Unknown, Base, Dog, Cat };
>
> struct Identity_t
>    {
>      Type_t Type;
>      union
>        {
>          Base_t* pBase;
>          Dog_t*  pDog;
>          Cat_t*  pCat;
>        };
>
>      Identity_t() : Type(Unknown) { pBase = nullptr; }
>    };
>
> Identity_t Identity(Base_t* pBase)
>    {
>      Identity_t I;
>      if ((I.pDog = dynamic_cast<Dog_t*>(pBase))) { I.Type = Dog; return I;
> }
>      if ((I.pCat = dynamic_cast<Cat_t*>(pBase))) { I.Type = Cat; return I;
> }
>      return I;
>    }
>
>
> // And using it like this:
> // p is the address of a derived object, ie. Dog_t* or Cat_t*
>
> auto I = Identity(p);
> if (I.Type == Dog)
>    { // use I.pDog to access it
>      auto& X = *I.pDog;
>      X.print();
>    }
> else if (I.Type == Cat)
>    { // use I.pCat to access it
>      auto& X = *I.pCat;
>      X.print();
>    }
>
> ...
> // end of code
>
>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Polymorphism: via base pointer getting the original object
  2023-04-26 17:20 Polymorphism: via base pointer getting the original object U.Mutlu
  2023-04-26 17:33 ` Jonathan Wakely
@ 2023-04-26 17:35 ` Andrew Haley
  2023-04-26 17:55   ` U.Mutlu
  1 sibling, 1 reply; 4+ messages in thread
From: Andrew Haley @ 2023-04-26 17:35 UTC (permalink / raw)
  To: gcc-help

On 4/26/23 18:20, U.Mutlu wrote:
> How best to do this?

In a word or two, don't. This is basic OOP: all accesses to an object should
be via its (possibly virtual) member functions. There's nothing to stop you
from defining

   virtual Dog_t Base_t::as_dog() { return nullptr; }

in the base class, and overriding it as

   virtual Dog_t Dog_t::as_dog() { return this; }

in the derived class. If you really need to...

Can I remind you that this list is for specific GCC help, not C++ language issues?

Thanks.

-- 
Andrew Haley  (he/him)
Java Platform Lead Engineer
Red Hat UK Ltd. <https://www.redhat.com>
https://keybase.io/andrewhaley
EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Polymorphism: via base pointer getting the original object
  2023-04-26 17:35 ` Andrew Haley
@ 2023-04-26 17:55   ` U.Mutlu
  0 siblings, 0 replies; 4+ messages in thread
From: U.Mutlu @ 2023-04-26 17:55 UTC (permalink / raw)
  To: Andrew Haley, gcc-help

Andrew Haley via Gcc-help wrote on 04/26/23 19:35:
> On 4/26/23 18:20, U.Mutlu wrote:
>> How best to do this?
>
> In a word or two, don't. This is basic OOP: all accesses to an object should
> be via its (possibly virtual) member functions. There's nothing to stop you
> from defining
>
>    virtual Dog_t Base_t::as_dog() { return nullptr; }
>
> in the base class, and overriding it as
>
>    virtual Dog_t Dog_t::as_dog() { return this; }
>
> in the derived class. If you really need to...

Thx, just tried this out, but it's not of much help as one has to know the 
type in advance, ie. at compile time.

> Can I remind you that this list is for specific GCC help, not C++ language
> issues?
>
> Thanks.

Oh, sorry, I forgot. Can you recommend a mailing list where such issues are 
discussed? Thx.


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2023-04-26 17:55 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-26 17:20 Polymorphism: via base pointer getting the original object U.Mutlu
2023-04-26 17:33 ` Jonathan Wakely
2023-04-26 17:35 ` Andrew Haley
2023-04-26 17:55   ` U.Mutlu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).