Inheritance and references

P

Paul N

I was under the impression that a reference had to be of exactly the
same type as the thing it was a reference to. See for instance FAQ
8.1, which states emphatically "please do not think of a reference as
a funny looking pointer to an object. A reference is the object. It is
not a pointer to the object, nor a copy of the object. It is the
object."

However, a couple of posts recently have suggested that it is all
right for a reference of one type to point to an object of a derived
type. I assumed at first that these were mistaken but I have tried it
out on both Turbo C++ and VC++ and it seems to work. For instance:

#include <stdio.h>

class Base { int a; };

class Derived : public Base { int b; };

int main(void) {
Derived d;
Base& br = d;

printf("Size of Base %d, Derived %d, d %d, br %d\n",
(int) sizeof(Base),
(int) sizeof(Derived),
(int) sizeof(d),
(int) sizeof(br));
}

This gives br having a size of 2, but d having a size of 4. Surely
these things can't be the same?

I could understand it if a reference were simply a funny-looking
pointer, but the FAQ teaches strongly against this. How can things be
the same if they're different?

Thanks for any explanation.
Paul.
 
J

James Kanze

I was under the impression that a reference had to be of
exactly the same type as the thing it was a reference to. See
for instance FAQ 8.1, which states emphatically "please do not
think of a reference as a funny looking pointer to an object.
A reference is the object. It is not a pointer to the object,
nor a copy of the object. It is the object."

It is the object, sort of. In the same sense as a named
variable is the object.
However, a couple of posts recently have suggested that it is
all right for a reference of one type to point to an object of
a derived type.

Using the above terminology, a reference doesn't point:). It
may refer to a derived type, however (unlike a non-reference
named variable).

The standard goes to great lengths to say that references aren't
pointers---they don't even have an existance independently of
the object they refer to. But others have pointed out that
thinking of them as automatically dereferenced pointers results
in roughly the same semantics. It really doesn't matter much,
as long as you understand what is happening. References do
allow dynamic type and static type to differ. (Is this really
any different than allowing a const reference to refer to
a non-const object?)
I assumed at first that these were mistaken but I have tried it
out on both Turbo C++ and VC++ and it seems to work. For instance:
#include <stdio.h>
class Base { int a; };
class Derived : public Base { int b; };
int main(void) {
Derived d;
Base& br = d;
printf("Size of Base %d, Derived %d, d %d, br %d\n",
(int) sizeof(Base),
(int) sizeof(Derived),
(int) sizeof(d),
(int) sizeof(br));
}
This gives br having a size of 2, but d having a size of 4. Surely
these things can't be the same?

Expressions have both static and dynamic types. A sizeof
expression always returns the size of the static type.
I could understand it if a reference were simply a funny-looking
pointer, but the FAQ teaches strongly against this. How can things be
the same if they're different?

Because they're not the same everywhere? It's largely
a question of vocabulary, and how you want to talk about
something.
 
M

Michael Tsang

Paul said:
#include <stdio.h>

class Base { int a; };

class Derived : public Base { int b; };

int main(void) {
Derived d;
Base& br = d;

printf("Size of Base %d, Derived %d, d %d, br %d\n",
(int) sizeof(Base),
(int) sizeof(Derived),
(int) sizeof(d),
(int) sizeof(br));
}

This gives br having a size of 2, but d having a size of 4. Surely
these things can't be the same?
That's the compiler evaluates sizeof only by the static type of the
expression (which is a Base&), but not the actual contents of the object.
 
J

Juha Nieminen

Paul N said:
However, a couple of posts recently have suggested that it is all
right for a reference of one type to point to an object of a derived
type.

Well, an object of the derived type *is* an object of the base type.
That's what the "is-a" relationship means.

If eg. a function takes a reference to a base class object, you can
give it an object of a class derived from that base class.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top