|
![](/i/fill.gif) |
Warp wrote:
> Invisible <voi### [at] dev null> wrote:
>> I just want to make sure I've got this absolutely straight in my head.
>> So... a reference is the same as a pointer, except that it has nicer
>> syntax, and you cannot change where it points to?
>
> And there's no null reference. A reference must always be given a
> valid object.
Ah yes - because you can't change it later, it must always be pointed at
something when you first create it.
> (Of course it can be given an invalid one by abusing
> ugly casting, but then your program will crash or behave erratically.)
Yeah. Don't do that! ;-)
> A union is a space-saving trick from C.
> A union is a way to put both elements at the same location:
>
> union Element
> {
> int i;
> double d;
> };
>
> Now sizeof(Element) == sizeof(double)
>
> The element is interpreted as an int if you access 'i' and as a double
> if you access 'd'. Of course there's absolutely no type safety here.
> If it was initialized as a double and you access it as an integer, you'll
> get garbage (whatever the first bytes of the double look like when seen
> as an integer).
Right. That's what I figured.
> Since there's no way of distinguishing which type of element it is,
> unions are often used like this:
>
> struct Element
> {
> enum Type { Int, Double };
>
> Type type;
> union
> {
> int i;
> double d;
> };
> };
Right. So you add a tag to tell you what kind of thing it is.
(Incidentally, this is basically what Haskell's "algebraic datatypes"
are. You can write something like "data Number = IntNumber Int |
DoubleNumber Double", and now any function that accepts a "Number" will
accept either an Int or a Double. And it's type-safe because the value
is tagged with a name such as "IntNumber".)
> Some people use unions for fancier tricks, such as:
>
> struct Matrix
> {
> union
> {
> double v[3][3];
> struct
> {
> double v00, v01, v02, v10, v11, v12, v20, v21, v22;
> };
> };
> };
>
> Now if you have some "Matrix m;", m.v[0][1] and m.v01 are the same thing.
That's just devious! :-O
> Unions are not very compatible with C++ classes. If you had this:
>
> union Element
> {
> int i;
> std::string s;
> };
>
> and then you instantiate it like "Element e;", then what should the
> compiler do about the string? Should it call its constructor or not?
> Likewise: What happens when 'e' is destroyed? Should the destructor
> of the string be called or not?
Ooo, ouch!
> Thus the current standard just says that you can't use class instances
> as members of a union, period.
Fair enough.
Actually, it just occurred to me: what would happen if you had a union
of two classes that are both related? When you do foo.bar(), how would
it know which bar() you meant? No wonder they don't allow this stuff...
>> Here's a perverse question: can a union have member functions?
>
> Yes, but they cannot be virtual.
OK. Well I doubt I'll be using unions much anyway, but hey. ;-)
>> My understanding is that when you create variables, they start off
>> containing junk unless you initialise them (or their types have
>> constructors which initialise them to something specific). Is that correct?
>
> Right (although in some situations it might not be immediately clear
> whether the variable is actually being initialized or not).
Yeah, "int x;" and "string x" both look pretty similar, but if I
understand this right, the latter gets initialised (to an empty string?)
>> Does C++ have a concept of a "null pointer" - i.e., a pointer that
>> doesn't point to anything valid, and can be detected as such?
>
> Yes: 0.
So I say "int *x = 0;" and then later I can check that "if (x == 0) ..."?
Does C++ check whether a pointer you're deferencing is zero? Or will it
just segfault?
>> How does memory allocation work in C++? If a program fills the heap, do
>> you have to explicitly *do* something to enlarge the heap, or does it
>> grow automatically? Does it shrink back again after you release things,
>> or do you have to request that manually?
>
> That's something the compiler and the OS take care of. You usually don't
> have to worry about it.
OK.
Post a reply to this message
|
![](/i/fill.gif) |