Re: C++ Conversion functions for pointers
From: Paul (paulmmm01_at_hotmail.com)
Date: 05/02/04
- Next message: Bibi: "Re: C declaration"
- Previous message: Jeff Schwab: "Re: C declaration"
- In reply to: B. v Ingen Schenau: "Re: C++ Conversion functions for pointers"
- Next in thread: B. v Ingen Schenau: "Re: C++ Conversion functions for pointers"
- Reply: B. v Ingen Schenau: "Re: C++ Conversion functions for pointers"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: 2 May 2004 06:26:32 -0700
"B. v Ingen Schenau" <bart@ingen.ddns.info> wrote in message news:<c6vq8i$ghbea$1@ID-135549.news.uni-berlin.de>...
> Paul wrote:
>
> > "B. v Ingen Schenau" <bart@ingen.ddns.info> wrote in message
> > news:<c6t5so$8rtcf$1@ID-135549.news.uni-berlin.de>...
> >> Paul wrote:
> >>
> >> > Hi group,
> >> > I have worked out a way to return different types by subscript from a
> >> > Variant class with the prerequesites that UDT's
> >> > a)inherit from a Variant class and..
> >> > b)they oveload the assignment operator to take an argument of type
> >> > Variant&.
> >>
> >> The only flaw is that it does not work, because you are invoking
> >> undefined behaviour. :-(
> >
> > No your incorrect.
>
> No, I _am_ correct. One of the ways UB can manifest itself in is that the
> code appears to work, or appears to work in some cases but not in others.
> One particular nasty form is that it appears to work always, except when the
> program is being demonstrated to your boss and/or an important client.
>
What exactly are you saying is causing UB here?
I thought you were meaning the subscript operator function but now I'm
not so sure what your talking about.
> <snip>
> >> > template<class DEFAULT_TYPE=Variant>
> >> > class ObjArray{
> >> > public:
> >> > ObjArray():itsSize(0){std::cout<<"Construcing(Default ObjArray).\n";}
> >> > ObjArray(int size):itsSize(size){
> >> > std::cout<<"Construcing ObjArray.\n";
> >> > itsArray = new DEFAULT_TYPE[size];
> >>
> >> Because itsArray always has the type Variant*, this will only work if
> >> DEFAULT_TYPE happens to be Variant.
> >
> > No you don't seem to understand what I am trying to do.
>
> I do understand what you are trying to do, but it just does not work that
> way.
Well just to make it clear..
I know I can create an array of Variant pointers and assign to these
pointers either Variants or classes derived from variants.
And whether these pointers are in array or not
i.e:
Variant* = new Variant(int);
Variant* = new ClassDerivedfromVariant;
As you can see for built in types I need to create a Variant type ,
converted to the built in type. So If I were allocating dependant on
an argument I would first need to check to see if the argument was a
Variant(or Derived from Variant) before allocating.
This is a bit messy and I would like to do this in one statement.
>
> > Variant can convert to/from built in types. The code posted is
> > stripped down to simply int types.
> > Also as I stated, any UDT's must derived form Variant therefore a UDT
> > can be assigned to a Variant*.
>
> That is all very true when you have a *single* object, but when you start to
> create an array of them, a different set of rules comes into play.
> The most important one you are running into is that the conversions that
> apply to a single object, are not valid for an array of objects. And that
> includes the conversion from pointer to derived class to pointer to base
> class.
Yes but I would have an array of Variant pointers, Which is possible
is it not?
>
> >
> >> For any other type, you will either get a compile error, or you invoke UB
> >> later down the line.
> >
> > No
> > I can use types that derives from Variants for UDT's but for built in
> > types what happens is..
>
> For types not derived from Variant, including the built-in types, you get a
> compile error. For the types derived from Variant, you just get undefined
> behaviour, which the compiler may or may not warn about.
Yes as it stands it doesn't work correctly, but this is why I am
asking the question.
>
> > The variant conversion constructor is called for that particular type.
> > i.e:
> > Variant(int x):intData(x){std::cout<<"Construcing Variant(int).\n";}
> > So the object is actually a variant but if all the main operators are
> > overloaded correctly it will behave like an integer.
> >
> > But the problem I am having is converting an int pointer to a Variant
> > pointer.
>
> And that conversion is not possible in any meaningful way.
> Just because you can convert a single int into a single Variant, does not
> mean that you can do the same with an array of them.
> If you want to convert an array of int objects into an array of Variant
> objects, you must first create the array of Variants, and then assign each
> int individually.
I wasn't trying to convert an array. My problem is when I try to
allocate memory for int I get an int* (obviously).
I don't want this I wan't to get a Variant*, so I am asking if there
is a way to change the default behaviour, perhaps by operator overload
or by using conversion functions or both.
I realise this part of my code had problems and perhaps I should have
defined more clearly what I was trying to do. The reason being I am
unsure about how best to construct the data in the Array. I don't yet
know if an array of Variant* 's is the best solution.
Perhaps I could store the data in arrays of different types and then
have some kind of logic inbetween that encapsulates indexing of all
the arrays into one.
SO I am keeping an open mind about how best to store the different
types of Variants until I have explored a few different possibilities.
It's more a design issue than anything.
I have 3 or more options in my mind at the moment and I'm not sure
which would be best.
1) Create an array of variant pointers and test for variant classes
before allocation.
2) Create an array of variant pointers and look into overloading new.
3) create an array of variant pointers for UDT's and and array of
variants(non pointer) for built in types, then create some kind of
indexing map to make the two arrays behave like one.
>
> >>
> >> > }
> >> > ~ObjArray(){std::cout<<"Destrucing ObjArray.\n"; delete [] itsArray;}
> >>
> >> You can not use the delete[] operator if there is a mismatch between the
> >> static and dynamic types of its operand.
> > I had worried about this here but i'm not sure what your saying is the
> > same as what I was worrying about.
> >
> > SO say I have the classes Class1 and Class2 which both derive from
> > Varaint.
> > if I create an array of varaint pointers and assign a mixture of
> > CLass1's and Class2's to these pointers then I must delete each one
> > individually?
>
> Just to get this straight, C++ does not support arrays of mixed types, so
> this will not work:
>
> class Variant { /* ... */ };
>
> class Class1: public Variant { /* ... */ };
>
> class Class2: public Variant { /* ... */ };
>
> int main()
> {
> Variant *array;
>
> array = new Variant[3];
>
> array[0] = 3; /* This is the same as array[0] = Variant(3); */
> array[1] = Class1(); /*!!! Only the Variant part of Class1 actually gets
> assigned. */
> array[2] = Class2(); /*!!! Only the Variant part of Class2 actually gets
> assigned. */
>
> delete[] array;
> }
>
> If you want to simulate an array of mixed types, you must create an array of
> pointers:
>
> class Variant { /* ... */ };
>
> class Class1: public Variant { /* ... */ };
>
> class Class2: public Variant { /* ... */ };
>
> int main()
> {
> Variant **array;
>
> array = new Variant*[3];
>
> array[0] = new Variant(3);
> array[1] = new Class1();
> array[2] = new Class2();
>
> for (int i=0; i<3; i++)
> delete array[i];
> delete[] array;
> }
>
> And with all of this, you must remember that for each call to new that is
> encountered during the execution, a matching call to delete must be
> executed. The same holds for new[] and delete[].
>
I realize I need to create an array of Variant*.
This is not the important part though, well it's important but..
It doesn't matter at the moment if I test it with
...
private:
Variant* data1;
Variant* data2;
...
because an array can always be constructed afterwards, the problem is
in assigning Variant(int) to a Variant pointer, because it doesn't fit
in the the sysntax of assigning a derived class.
> >
> >
> >> So, in normal language, you can not use 'delete[] itsArray' if itsArray
> >> does not point at an array of objects of type Variant.
> > Or a subclass of Varaint? ( A class that derives from Variant ).
>
> No, the array-form of operator delete can not be used on subclasses of
> Variant.
ok yeah I was getting confused there, delete[] should only be used to
match new[] right?
>
> >
> >> This is because otherwise the compiler does not know the size of each
> >> object, which makes it impossible to call the destructors for the objects
> >> with indices 1 and higher.
> >
> > But the compiler can use the virtual destructor no?
>
> But if the compiler does not know how large each object in the array is, how
> can it generate code to access the second, thrird, etc. object in the
> array?
Yeah ok I see your point about the new[] delete[] thing.
I was not focussing on that part to be honest, it doesn't matter if I
use an array at this point or not but if I do I need an array of
Variant*. Then I can assign any type to this ( with the prerequisites
) .
>
> If you have an array of Class1 objects and you assign the address to a
> Varian pointer, then the compiler can not take into account the size taken
> up by the additional members of Class1 when calculating the address of the
> second object in the array.
ok I understand this.
>
> <snip>
> >> >
> >> > AHA TIA
> >> > Paul.
> >> >
> >> Bart v Ingen Schenau
> >
> <snip>
> > Paul.
>
> Bart v Ingen Schenau
So now you can see that I have an array class that can overload the
subscript operator to return a Variant& . My problem is that I don't
know what is best way to store the data in the array because the data
will be of different types, the most obvious solution being to store
in an Array of Variant*'s.
Then I need to allocate something like this:
(phsuedo)
if( T == Variant or Derived)
vpArray[i] = new T;
else
vpArray[i] = new Variant(T);
This is a bit of a problem(I don't like it), and I was looking for a
better solution.
I think a better solution may be to overload 'new' for Variant but I
have no experience with this and find it a bit daunting.
I would appreciate it if you could give some advice on this
AHA & TIA.
Paul.
- Next message: Bibi: "Re: C declaration"
- Previous message: Jeff Schwab: "Re: C declaration"
- In reply to: B. v Ingen Schenau: "Re: C++ Conversion functions for pointers"
- Next in thread: B. v Ingen Schenau: "Re: C++ Conversion functions for pointers"
- Reply: B. v Ingen Schenau: "Re: C++ Conversion functions for pointers"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|