Skip to content

Module 06 Solutions

Download Module 06 Solutions

Type detection and conversion.

ScalarConverter.cpp
void ScalarConverter::convert(const std::string& literal) {
// Detect type
if (isChar(literal))
fromChar(literal);
else if (isInt(literal))
fromInt(literal);
else if (isFloat(literal))
fromFloat(literal);
else if (isDouble(literal))
fromDouble(literal);
else
std::cout << "Invalid literal" << std::endl;
}
bool ScalarConverter::isChar(const std::string& s) {
return s.length() == 1 && !isdigit(s[0]);
}
void ScalarConverter::fromDouble(const std::string& s) {
double d = strtod(s.c_str(), NULL);
// char
if (d < 0 || d > 127 || isnan(d) || isinf(d))
std::cout << "char: impossible" << std::endl;
else if (!isprint(static_cast<int>(d)))
std::cout << "char: Non displayable" << std::endl;
else
std::cout << "char: '" << static_cast<char>(d) << "'" << std::endl;
// int
if (d < INT_MIN || d > INT_MAX || isnan(d) || isinf(d))
std::cout << "int: impossible" << std::endl;
else
std::cout << "int: " << static_cast<int>(d) << std::endl;
// float & double
std::cout << std::fixed << std::setprecision(1);
std::cout << "float: " << static_cast<float>(d) << "f" << std::endl;
std::cout << "double: " << d << std::endl;
}

reinterpret_cast for pointer to integer conversion.

Serializer.hpp
class Serializer {
private:
Serializer();
public:
static uintptr_t serialize(Data* ptr);
static Data* deserialize(uintptr_t raw);
};
Serializer.cpp
uintptr_t Serializer::serialize(Data* ptr) {
return reinterpret_cast<uintptr_t>(ptr);
}
Data* Serializer::deserialize(uintptr_t raw) {
return reinterpret_cast<Data*>(raw);
}

dynamic_cast for runtime type checking.

main.cpp
// Pointer version: returns NULL on failure
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;
}
// Reference version: throws on failure
void identify(Base& p) {
try {
(void)dynamic_cast<A&>(p);
std::cout << "A" << std::endl;
return;
} catch (...) {}
try {
(void)dynamic_cast<B&>(p);
std::cout << "B" << std::endl;
return;
} catch (...) {}
try {
(void)dynamic_cast<C&>(p);
std::cout << "C" << std::endl;
} catch (...) {}
}
// Random generator
Base* generate() {
srand(time(NULL));
switch (rand() % 3) {
case 0: return new A();
case 1: return new B();
case 2: return new C();
}
return NULL;
}