mixed.cc
#include <iostream> // cout, endl
#include <cstdlib> // EXIT_SUCCESS
using std::cout;
using std::endl;
class A {
public:
void M1() { cout << "a1, "; }
virtual void M2() { cout << "a2"; }
};
class B : public A {
public:
void M1() { cout << "b1, "; }
void M2() { cout << "b2"; }
};
int main(int argc, char** argv) {
A a;
B b;
A* a_ptr_a = &a;
A* a_ptr_b = &b;
// B* ba_ptr = &a; // compiler error
B* b_ptr_b = &b;
a_ptr_a->M1();
a_ptr_a->M2();
cout << endl;
a_ptr_b->M1();
a_ptr_b->M2();
cout << endl;
b_ptr_b->M1();
b_ptr_b->M2();
cout << endl;
return EXIT_SUCCESS;
}
badctor.cc
// Base has no default constructor
class Base {
public:
Base(int y) : y(y) { }
int y;
};
// Compiler error when you try to instantiate a D1, as D1’s
// synthesized default constructor needs to invoke Base's default
// constructor.
class Der1 : public Base {
public:
int z;
};
// Works.
class Der2 : public Base {
public:
Der2(int y, int z) : Base(y), z(z) { }
int z;
};
int main(int argc, char **argv) {
Base b(1); // OK
Der2 d2(1, 2); // OK
// Der1 d1; // compiler error
return 0;
}
goodctor.cc
// Base has a default constructor.
class Base {
public:
int y;
};
// Works.
class Der1 : public Base {
public:
int z;
};
// Works.
class Der2 : public Base {
public:
Der2(int z) : z(z) { }
int z;
};
int main(int argc, char **argv) {
Base b; // OK
Der2 d2(1); // OK
Der1 d1; // OK
return 0;
}
baddtor.cc
#include <iostream>
class Base {
public:
Base() { std::cout << "Base()" << std::endl; x = new int; }
~Base() { std::cout << "~Base()" << std::endl; delete x; }
int* x;
};
class Der1 : public Base {
public:
Der1() { std::cout << "Der1()" << std::endl; y = new int; }
~Der1() { std::cout << "~Der1()" << std::endl; delete y; }
int* y;
};
int main(int argc, char** argv) {
Base* b0ptr = new Base;
Base* b1ptr = new Der1;
delete b0ptr; // OK
delete b1ptr; // leaks Der1::y
return 0;
}
slicing.cc
class Base {
public:
Base(int x) : x(x) { }
int x;
};
class Der1 : public Base {
public:
Der1(int y) : Base(16), y(y) { }
int y;
};
int main(int argc, char** argv) {
Base b(1);
Der1 d(2);
b = d; // what happens to y?
// d = b; // compiler error
}
static_cast
class A {
public:
int x;
};
class B {
public:
float x;
};
class C : public B {
public:
char x;
};
int main(int argc, char** argv) {
B b; C c;
// compiler error
A* aptr = static_cast<A*>(&b);
// OK
B* bptr = static_cast<B*>(&c);
// compiles, but dangerous
C* cptr = static_cast<C*>(&b);
return 0;
}
dynamiccast.cc
#include <cassert>
class Base {
public:
// virtual function included to make hierarchy polymorphic
virtual void foo() { }
float x;
};
class Der1 : public Base {
public:
char x;
};
int main(int argc, char** argv) {
Base b; Der1 d;
// OK (run-time check passes)
Base* bptr = dynamic_cast<Base*>(&d);
assert(bptr != nullptr);
// OK (run-time check passes)
Der1* dptr = dynamic_cast<Der1*>(bptr);
assert(dptr != nullptr);
// Run-time check fails, so the cast returns nullptr
bptr = &b;
dptr = dynamic_cast<Der1*>(bptr);
assert(dptr != nullptr);
return 0;
}
constcast.cc
void foo(int* x) {
(*x)++;
}
void bar(const int* x) {
// foo(x); // compiler error
foo(const_cast<int*>(x)); // succeeds
}
int main(int argc, char** argv) {
int x = 7;
bar(&x);
return 0;
}