|
![](/i/fill.gif) |
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. (Of course it can be given an invalid one by abusing
ugly casting, but then your program will crash or behave erratically.)
> If I'm understanding this correctly, a "union" is like several structs
> with the same base address, and you can treat it was one struct or the
> other struct, and it's up to you to remember which which struct you're
> currently using it is. (I.e., the language itself provides no way to
> distinguish.)
A union is a space-saving trick from C. Suppose you have an array of
elements, and each element can be either an int or a double. You could
do that by making the element a struct with an int and a double:
struct Element
{
int i;
double d;
};
sizeof(Element) == sizeof(int) + sizeof(double)
But since the element is always either an int or a double, never both
at the same time, that feels like a waste of space: You are needlessly
allocating space for both things, even though always one of the things
is always unused.
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).
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;
};
};
(Of course in this particular case there's no space saving, but you
get the idea.)
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.
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?
It would be useless (and wrong) to construct it if what you want to do
is to use the int. It would be would be wrong to not to construct it
if you want to use the string.
(Constructing it would be wrong because if you then modify the int,
you will be corrupting the string object, and undefined behavior will
follow.)
Likewise: What happens when 'e' is destroyed? Should the destructor
of the string be called or not?
Thus the current standard just says that you can't use class instances
as members of a union, period.
The next C++ standard will relax this limitation a bit in certain cases,
but overall C++ has inherited unions from C and they are not very C++'ish
constructs.
> Here's a perverse question: can a union have member functions?
Yes, but they cannot be virtual.
> 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).
> 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.
> 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.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |