Instructor: James Riely
x
has static type Animal
, dynamic type Bird
/Cat
class Animal { public: string to_string() { return "Animal"; } };
class Bird: public Animal { public: string to_string() { return "Bird"; } };
class Cat: public Animal { public: string to_string() { return "Cat"; } };
Animal *xs[] = { new Bird(), new Cat() };
for (Animal *x : xs) cout << x->to_string() << endl;
$ g++ -std=c++11 -o animal1 animal1.cpp && ./animal1
Animal
Animal
x
has static type Animal
, dynamic type Bird
/Cat
class Animal { public: virtual string to_string() { return "Animal";
class Bird: public Animal { public: virtual string to_string() { return "Bird"; }
class Cat: public Animal { public: virtual string to_string() { return "Cat"; }
Animal *xs[] = { new Bird(), new Cat() };
for (Animal *x : xs) cout << x->to_string() << endl;
$ g++ -std=c++11 -o animal2 animal2.cpp && ./animal2
Bird
Cat
x
has static type Animal
, dynamic type Bird
/Cat
class Animal { public: virtual string to_string() const { return "Animal"; } };
class Bird: public Animal { public: virtual string to_string() const { return "Bird"; } };
class Cat: public Animal { public: virtual string to_string() const { return "Cat"; } };
const Animal &x = Bird(); // no arrays of references
cout << x.to_string() << endl;
$ g++ -std=c++11 -o animal2r animal2r.cpp && ./animal2r
Bird
x
has static type Animal
, dynamic type Animal
class Animal { public: virtual string to_string() { return "Animal";
class Bird: public Animal { public: virtual string to_string() { return "Bird"; }
class Cat: public Animal { public: virtual string to_string() { return "Cat"; }
Animal xs[] = { Bird(), Cat() };
for (Animal x : xs) cout << x.to_string() << endl;
$ g++ -std=c++11 -o animal3 animal3.cpp && ./animal3
Animal
Animal
class Animal { char a[3]; };
class Bird : public Animal { char b[5]; };
class Cat : public Animal { char c[7]; };
Animal xs[] = { Bird(), Cat() };
cout << "sizeof(Animal) = " << sizeof(Animal) << endl;
cout << "sizeof(Bird) = " << sizeof(Bird) << endl;
cout << "sizeof(Cat) = " << sizeof(Cat) << endl;
cout << "sizeof(xs) = " << sizeof(xs) << endl;
$ g++ -std=c++11 -o animal4 animal4.cpp && ./animal4
sizeof(Animal) = 3
sizeof(Bird) = 8
sizeof(Cat) = 10
sizeof(xs) = 6
xs
does not have enough space to hold a Bird
or Cat
class Animal { char a[3]; };
class Bird : public Animal { char b[5]; };
class Cat : public Animal { char c[7]; };
Animal *xs[] = { new Bird(), new Cat() };
cout << "sizeof(Animal*)= " << sizeof(Animal*) << endl;
cout << "sizeof(Bird*) = " << sizeof(Bird*) << endl;
cout << "sizeof(Cat*) = " << sizeof(Cat*) << endl;
cout << "sizeof(xs) = " << sizeof(xs) << endl;
$ g++ -std=c++11 -o animal5 animal5.cpp && ./animal5
sizeof(Animal*)= 8
sizeof(Bird*) = 8
sizeof(Cat*) = 8
sizeof(xs) = 16
class Animal { char a[3]; public: string to_string() { return "Animal"; } };
class Bird : public Animal { char b[5]; public: string to_string() { return "Bird"; } };
class Cat : public Animal { char c[7]; public: string to_string() { return "Cat"; } };
cout << "sizeof(Animal) = " << sizeof(Animal) << endl;
cout << "sizeof(Bird) = " << sizeof(Bird) << endl;
cout << "sizeof(Cat) = " << sizeof(Cat) << endl;
$ g++ -std=c++11 -o animal6 animal6.cpp && ./animal6
sizeof(Animal) = 3
sizeof(Bird) = 8
sizeof(Cat) = 10
class Animal { char a[3]; public: virtual string to_string() { return "Animal"; } };
class Bird : public Animal { char b[5]; public: virtual string to_string() { return "Bird"; } };
class Cat : public Animal { char c[7]; public: virtual string to_string() { return "Cat"; } };
cout << "sizeof(Animal) = " << sizeof(Animal) << endl;
cout << "sizeof(Bird) = " << sizeof(Bird) << endl;
cout << "sizeof(Cat) = " << sizeof(Cat) << endl;
$ g++ -std=c++11 -o animal7 animal7.cpp && ./animal7
sizeof(Animal) = 16
sizeof(Bird) = 16
sizeof(Cat) = 24
class Animal { char a[3]; public: virtual string to_string() { return "Animal"; } };
class Cat : public Animal { char c[7]; public: virtual string to_string() { return "Bird"; }
virtual void f() { } };
cout << "sizeof(Animal) = " << sizeof(Animal) << endl;
cout << "sizeof(Cat) = " << sizeof(Cat) << endl;
$ g++ -std=c++11 -o animal7 animal7.cpp && ./animal7
sizeof(Animal) = 16
sizeof(Cat) = 24
$ g++ -S singlefields.cpp
%rax
, %rdx,
, %rdi,
...
%eax
is half of %rax
%rdi
%rip
%rbp
%rsp
%rbp-8
, %rax
movq -8(%rbp), %rax
movl -8(%rbp), %eax
void greetEnglish () { printf ("Hello\n"); }
void greet () { greetEnglish (); }
greetEnglish:
...
greet:
pushq %rbp
movq %rsp, %rbp
callq greetEnglish
popq %rbp
retq
void greetEnglish () { printf ("Hello\n"); }
void greetSpanish () { printf ("Hola\n"); }
void greet (bool useEnglish) {
void (*p) (); // p is a function pointer
if (useEnglish) {
p = &greetEnglish;
} else {
p = &greetSpanish;
}
(*p) (); // invoke function p points to
}
greet:
pushq %rbp
movq %rsp, %rbp
cmpl $0, %rdi /* rdi = useEnglish */
je .ELSE
leaq $greetEnglish(%rip), %rax
jmp .ENDIF
.ELSE:
leaq $greetSpanish(%rip), %rax
.ENDIF:
callq *%rax /* rax = p */
popq %rbp
retq
#include <iostream>
using namespace std;
class B {
public:
int b1;
int b2;
};
class D : public B {
public:
int d1;
int d2;
};
int main () {
D *d = new D ();
d->d1 = 9032;
d->d2 = 3293;
d->b1 = 2948;
d->b2 = 8432;
B *b = (B*) d;
int x1 = b->b1;
int x2 = b->b2;
cout << "Values are: " << x1 << ", " << x2 << endl;
}
Values are: 2948, 8432
#include <iostream>
using namespace std;
class B {
public:
int b1;
int b2;
virtual void f1 () { cout << "B.f1 "; }
virtual void f2 () { cout << "B.f2 "; }
};
class D : public B {
public:
int d1;
int d2;
virtual void f2 () { cout << "D.f2 "; }
virtual void f3 () { cout << "D.f3 "; }
};
int main () {
D *d = new D ();
d->b1 = 2948;
d->f1 ();
d->f2 ();
d->f3 ();
B *b = (B*) d;
b->f1 ();
b->f2 ();
// Not allowed, because f3 is not member function of class B:
// b->f3 ();
}
B.f1 D.f2 D.f3 B.f1 D.f2
#include <iostream>
using namespace std;
class B {
public:
int b1;
int b2;
};
class F {
public:
int f1;
int f2;
};
class D : public B, public F {
public:
int d1;
int d2;
};
int main () {
D *d = new D ();
d->d1 = 1419;
d->d2 = 7292;
d->f1 = 9032;
d->f2 = 3293;
d->b1 = 2948;
d->b2 = 8432;
B *b = (B*) d;
int x1 = b->b1;
int x2 = b->b2;
F *f = (F*) d;
int y1 = f->f1;
int y2 = f->f2;
cout << "Values are: " << x1 << ", " << x2 << ", " << y1 << ", " << y2 << endl;
cout << "d: " << d << ", b: " << b << ", f:" << f << endl;
}
Values are: 2948, 8432, 9032, 3293
d: 0x7f83a9d05720, b: 0x7f83a9d05720, f:0x7f83a9d05728