Created
January 12, 2019 21:46
-
-
Save shintakezou/5f20c7fc9be4e61092c8e3d3088fe127 to your computer and use it in GitHub Desktop.
Dynamic overloading simple poc test (dynamic dispatching)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
// likely you'd like to use this someway; instead, this code | |
// simply ignores and accepts memory leaks. | |
//#include <memory> | |
#include <string> | |
#include <stack> | |
#include <sstream> | |
class Number; | |
class String; | |
struct Base | |
{ | |
virtual ~Base() {} | |
virtual const Base* op_sum(const String* s) const = 0; | |
virtual const Base* op_sum(const Number* n) const = 0; | |
virtual const Base* op_sum(const Base* b) const = 0; | |
virtual std::string str() const = 0; | |
}; | |
class Number : public Base | |
{ | |
public: | |
Number(int n); | |
const Base* op_sum(const Number* n) const final override; | |
const Base* op_sum(const String* s) const final override; | |
const Base* op_sum(const Base* b) const final override; | |
int value() const; | |
std::string str() const final override; | |
private: | |
int n_; | |
}; | |
class String : public Base | |
{ | |
public: | |
String(const std::string& s); | |
virtual const Base* op_sum(const Number* n) const final override; | |
virtual const Base* op_sum(const String* s) const final override; | |
const Base* op_sum(const Base* b) const final override; | |
std::string value() const; | |
std::string str() const final override; | |
private: | |
std::string s_; | |
}; | |
// implementation | |
Number::Number(int n) : n_(n) {} | |
int Number::value() const | |
{ | |
return n_; | |
} | |
const Base* Number::op_sum(const Number* n) const | |
{ | |
return new Number(n->value() + n_); | |
} | |
const Base* Number::op_sum(const String* s) const | |
{ | |
std::ostringstream ss; | |
ss << n_ << s->value(); | |
return new String(ss.str()); | |
} | |
std::string Number::str() const | |
{ | |
std::ostringstream ss; | |
ss << n_; | |
return ss.str(); | |
} | |
// dispatcher for Number | |
const Base* Number::op_sum(const Base* b) const | |
{ | |
if (dynamic_cast<const Number*>(b)) return this->op_sum(dynamic_cast<const Number*>(b)); | |
else if (dynamic_cast<const String*>(b)) return this->op_sum(dynamic_cast<const String*>(b)); | |
else throw std::runtime_error("dispatching error"); | |
} | |
String::String(const std::string& s) : s_(s) {} | |
std::string String::value() const | |
{ | |
return s_; | |
} | |
const Base* String::op_sum(const Number* n) const | |
{ | |
std::ostringstream ss; | |
ss << s_ << n->value(); | |
return new String(ss.str()); | |
} | |
const Base* String::op_sum(const String* s) const | |
{ | |
return new String(s_ + s->value()); | |
} | |
std::string String::str() const | |
{ | |
// should escape " in s_ | |
return "\"" + s_ + "\""; | |
} | |
// dispatcher for String | |
const Base* String::op_sum(const Base* b) const | |
{ | |
if (dynamic_cast<const Number*>(b)) return this->op_sum(dynamic_cast<const Number*>(b)); | |
else if (dynamic_cast<const String*>(b)) return this->op_sum(dynamic_cast<const String*>(b)); | |
else throw std::runtime_error("dispatching error"); | |
} | |
std::stack<const Base*> stack; | |
int main() | |
{ | |
stack.push(new Number(10)); | |
stack.push(new Number(11)); | |
stack.push(new Number(5)); | |
stack.push(new String("x")); | |
stack.push(new String("13")); | |
stack.push(new Number(12)); | |
stack.push(new String("a")); | |
stack.push(new String("bc")); | |
stack.push(new Number(1)); | |
stack.push(new Number(2)); | |
stack.push(new Number(3)); | |
// memory leaks? we don't care | |
const Base* o1; | |
const Base* o2; | |
const Base* r; | |
for (const auto ops : std::string{"++.+.+.+.+."}) { | |
switch (ops) { | |
case '+': | |
o2 = stack.top(); stack.pop(); | |
o1 = stack.top(); stack.pop(); | |
stack.push(o1->op_sum(o2)); | |
break; | |
case '.': | |
r = stack.top(); stack.pop(); | |
std::cout << r->str() << "\n"; | |
break; | |
default: | |
std::cerr << "unknown operator\n"; | |
break; | |
} | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment