cpp-exercises/rtti.cpp

81 lines
1.4 KiB
C++
Raw Normal View History

2014-04-26 16:31:07 +02:00
#include <iostream>
#include <stdexcept>
#include <typeinfo>
class Nail {
2014-08-24 14:43:35 +02:00
public:
2014-08-24 14:44:15 +02:00
explicit Nail(float length)
2014-08-24 14:43:35 +02:00
: length(length) {}
2014-04-26 16:31:07 +02:00
2014-08-24 14:43:35 +02:00
float getLength() {
return length;
}
2014-04-26 16:31:07 +02:00
2014-08-24 14:43:35 +02:00
private:
float length;
2014-04-26 16:31:07 +02:00
};
class Tool {
2014-08-24 14:43:35 +02:00
public:
virtual void use() {
std::cout << "Just using some tool." << std::endl;
}
2014-04-26 16:31:07 +02:00
};
class Hammer : public Tool {
2014-08-24 14:43:35 +02:00
public:
virtual void use() {
std::cout << "Hammer time!" << std::endl;
}
void use(Nail nail) {
std::cout << "The nail is " << nail.getLength() << " cm long"
<< std::endl;
}
2014-04-26 16:31:07 +02:00
};
class SledgeHammer : public Hammer {
2014-08-24 14:43:35 +02:00
public:
void use(Nail nail __attribute__((unused))) {
throw std::runtime_error("Can't use a sledge hammer on nails!");
}
2014-04-26 16:31:07 +02:00
};
void useSomeTool(Tool &tool) {
// RTTI gives up the type of the derived class.
std::cout << "Look, it's a " << typeid(tool).name() << "!" << std::endl;
// XXX What about subclasses of Hammer?
2014-08-18 23:45:07 +02:00
if (typeid(tool) == typeid(Hammer)) {
2014-04-26 16:31:07 +02:00
std::cout << "Stop! ";
}
tool.use();
// Or dynamic_cast it and use it on a nail
// XXX How to use a reference here?
Hammer* h = dynamic_cast<Hammer*>(&tool);
if (h) {
Nail nail(10);
h->use(nail);
}
}
int main() {
Tool tool;
Hammer hammer;
SledgeHammer sledgehammer;
useSomeTool(tool);
useSomeTool(hammer);
useSomeTool(sledgehammer);
}
// XXX http://en.cppreference.com/w/cpp/language/typeid
// XXX https://en.wikipedia.org/wiki/Dynamic_cast