Are array of pointers to different types possible in c++?
Asked Answered
S

8

7

Are array of pointers to different types possible in c++? with example please)

Showbread answered 16/10, 2009 at 18:57 Comment(1)
It wouldn't be an array, it would a type-erasing container. Array by definition (given way before existence of C and C++) is a collection of same-type objects. Relevant: https://mcmap.net/q/180491/-numpy-style-arrays-for-c-closedScraperboard
L
8

C++ is C with more stuff. So if you want to do it the C way, as above you just make an array of void pointers

void *ary[10];
ary[0] = new int();
ary[1] = new float();

DA.

If you want to do things the object oriented way, then you want to use a collection, and have all the things you going to be adding to the collection derive from the same base object class that can be added to the collection. In java this is "Object", C++ has no base object built in, but any collection library you use will have such a thing that you can subclass.

Larisa answered 16/10, 2009 at 19:2 Comment(8)
Given what you showed, how in the world are you to find out what types those pointers actually point to?Benzo
well, firstly, that wasn't the question, but to answer, there's all sorts of ways. 1) you can have a parallel array with the type encoded in it. 2) you can make the array elements structures of a type variable and a union with all the different kinds of things you might want to put in there. There's 2 just off the top of my head. I'm sure somebody else can come up with slicker alternatives.Larisa
@sbi: and you can also use RTTI.Continuant
@kriss: No, you can't. RTTI only works within polymorphic class hierarchies. Given a void*, the runtime system gives you nothing to find out what it points to.Benzo
@sbi: you are right. If he want's to use RTTI the OP should put all his structures in a common class hierarchy, however the base class can still be quite empty. Well, that's not much better than using a union plus a discriminating enum type.Continuant
in fact, it's basically the same thing. :-) Except there's more C++ gunky overhead. :-))Larisa
In fact, you have a array of pointers which are pointing to something which you don't know what it is. What can such a pointer be used for? Even if the answer is very old, it looks not very useful for any real world usage.Reliquiae
did klaus read the rest of the comments?Larisa
T
16

Usually if you want to have a collection of different "types" of pointers, you implement it in a way where they derive off a base class/interface and store a pointer to that base. Then through polymorphism you can have them behave as different types.

class Base
{
public:
    virtual void doSomething() = 0;
};

class A : public Base
{
    void doSomething() { cout << "A\n"; } 
};

class B : public Base
{
    void doSomething() { cout << "B\n"; } 
};

std::vector<Base*> pointers;
pointers.push_back(new A);
pointers.push_back(new B);
Tiflis answered 16/10, 2009 at 18:59 Comment(2)
I like this answer. I would add that you can also query which type is which dynamically, using dynamic_cast... Though some would argue that's a bad thing. :-)Leftwich
@asveikau: A dynamic_cast is, basically, a switch over types. And Switching over types is just a sign of (irrational) fear of polymorphism. When you're tempted to do that, use virtual functions instead.Benzo
C
9

An array of pointers to void has already been mentioned. If you want to make it practical and useful, consider using an array (or, better, vector) of boost::any.

Croup answered 16/10, 2009 at 19:2 Comment(0)
L
8

C++ is C with more stuff. So if you want to do it the C way, as above you just make an array of void pointers

void *ary[10];
ary[0] = new int();
ary[1] = new float();

DA.

If you want to do things the object oriented way, then you want to use a collection, and have all the things you going to be adding to the collection derive from the same base object class that can be added to the collection. In java this is "Object", C++ has no base object built in, but any collection library you use will have such a thing that you can subclass.

Larisa answered 16/10, 2009 at 19:2 Comment(8)
Given what you showed, how in the world are you to find out what types those pointers actually point to?Benzo
well, firstly, that wasn't the question, but to answer, there's all sorts of ways. 1) you can have a parallel array with the type encoded in it. 2) you can make the array elements structures of a type variable and a union with all the different kinds of things you might want to put in there. There's 2 just off the top of my head. I'm sure somebody else can come up with slicker alternatives.Larisa
@sbi: and you can also use RTTI.Continuant
@kriss: No, you can't. RTTI only works within polymorphic class hierarchies. Given a void*, the runtime system gives you nothing to find out what it points to.Benzo
@sbi: you are right. If he want's to use RTTI the OP should put all his structures in a common class hierarchy, however the base class can still be quite empty. Well, that's not much better than using a union plus a discriminating enum type.Continuant
in fact, it's basically the same thing. :-) Except there's more C++ gunky overhead. :-))Larisa
In fact, you have a array of pointers which are pointing to something which you don't know what it is. What can such a pointer be used for? Even if the answer is very old, it looks not very useful for any real world usage.Reliquiae
did klaus read the rest of the comments?Larisa
R
3

... if you use a void *, it's easy ;-)

Rarity answered 16/10, 2009 at 18:57 Comment(3)
can you give little example?))Showbread
and lead to potentially explosive situations!Rational
char *c_string = "Hello World"; MyCPlusPlusClass *obj = new MyCPlusPlusClass(); void *SomeArray[] = {c_string, obj}; If course, you'd damn well better have a way of remembering what's what. :-)Leftwich
T
3

Yes. Two ways:

• Pointers to a base class type, which point to objects of types derived from that base type.
• Untyped void * pointers, which must be cast manually to the actual object types they point to.

The first approach is standard object-oriented programming.

The second approach is useful for low-level programming (e.g., device drivers, memory management libraries, etc.), and is considered dangerous and suitable only for programmers who know exactly what they're doing. Obviously, it requires additional bookkeeping info to tell you what each pointer's real type is.

Traps answered 16/10, 2009 at 19:3 Comment(0)
A
1

Yes; just cast your pointers in the array to whatever type you want them to refer to.

Alternately, you could make your array an array of a union (with the union elements being the differing pointer types).

Antiquary answered 16/10, 2009 at 19:1 Comment(0)
S
0
#include <stdio.h>

int main(void)
{
  void * ptr[2];
  int *a;
  int b;

  ptr[0] = "[0] = \"This is a string & c does it better\", [1] = ";
  *a = 2;
  ptr[1] = a;
  b = *((int *) ptr[1]);
  printf("%s",  (char *) ptr[0] );
  printf("%i\n", b );

  return 0;
}
Sicanian answered 20/2, 2012 at 14:52 Comment(0)
L
0

Since nowadays it's advised to use smart pointers I decided to rewrite the first answer using them. Here is the code you would change. Pros of using smart pointers is that it is more memory safe than raw pointers.

std::vector<std::shared_ptr<Base>> pointers;
pointers.push_back(std::make_shared<A>());
pointers.push_back(std::make_shared<B>());
Levity answered 17/8 at 9:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.