Skip to content

Teaching Notes: Module 06

  • Four C++ cast types
  • When to use each cast
  • Type detection at runtime
  • Serialization concepts

  1. Check for char (single printable char)
  2. Check for int (all digits, optional sign)
  3. Check for float (has ‘f’ suffix)
  4. Check for double (decimal point, no ‘f’)
  5. Handle special: nan, inf, nanf, inff
  1. Not handling all edge cases

    • Empty string
    • Just ”-” or ”+”
    • Multiple decimal points
    • “nan” vs “nanf”
  2. Display format issues

    // Float/double should show .0 for whole numbers
    std::cout << std::fixed << std::setprecision(1);
    std::cout << 42.0f; // "42.0f" not "42f"
  3. Overflow detection

    • int overflow -> “impossible”
    • Non-displayable char -> “Non displayable”
  • Numeric conversions: static_cast

Convert pointer to integer and back.

uintptr_t Serializer::serialize(Data* ptr) {
return reinterpret_cast<uintptr_t>(ptr);
}
Data* Serializer::deserialize(uintptr_t raw) {
return reinterpret_cast<Data*>(raw);
}
  • reinterpret_cast - bit-level reinterpretation
  1. Empty Data struct

    • Subject requires non-empty Data
  2. Not testing round-trip

    Data d;
    uintptr_t raw = Serializer::serialize(&d);
    Data* result = Serializer::deserialize(raw);
    assert(result == &d); // Must be same address!

Must use dynamic_cast to identify types.

void identify(Base* p) {
if (dynamic_cast<A*>(p))
std::cout << "A" << std::endl;
else if (dynamic_cast<B*>(p))
std::cout << "B" << std::endl;
else if (dynamic_cast<C*>(p))
std::cout << "C" << std::endl;
}
void identify(Base& p) {
try {
(void)dynamic_cast<A&>(p);
std::cout << "A" << std::endl;
return;
} catch (...) {}
// Try B, C...
}
  1. Using typeid (forbidden)

    • <typeinfo> header is forbidden
  2. Pointer inside reference version

    • Subject forbids using pointer in reference version
  3. Base must be polymorphic

    • Need at least one virtual function (virtual destructor counts)
  • dynamic_cast - runtime type identification