Skip to content

Instantly share code, notes, and snippets.

@etam
Created May 17, 2014 11:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save etam/1dbc253542139727c535 to your computer and use it in GitHub Desktop.
Save etam/1dbc253542139727c535 to your computer and use it in GitHub Desktop.
baseless polymorphism in C++11
// http://channel9.msdn.com/Events/GoingNative/2013/Inheritance-Is-The-Base-Class-of-Evil
#include <iostream>
#include <memory>
#include <string>
#include <vector>
// ===== library ====
class Document
{
public:
class Object
{
private:
class Concept
{
public:
virtual ~Concept() = default;
virtual void draw_(std::ostream&, std::size_t) const = 0;
};
template <typename T>
class Model
: public Concept
{
private:
T data_;
public:
Model(T x)
: data_(std::move(x))
{}
void draw_(std::ostream& out, std::size_t position) const override
{
data_.draw(out, position);
}
};
std::shared_ptr<const Concept> self_;
public:
template <typename T>
Object(T x)
: self_{std::make_shared<Model<T>>(std::move(x))}
{}
void draw(std::ostream& out, std::size_t position) const
{
self_->draw_(out, position);
}
};
std::vector<Object> objects;
void draw(std::ostream& out, std::size_t position) const
{
out << std::string(position, ' ') << "<document>" << std::endl;
for (const auto& e : objects)
e.draw(out, position + 2);
out << std::string(position, ' ') << "</document>" << std::endl;
}
};
// ====== user ======
class MyClass
{
public:
int i;
void draw(std::ostream& out, std::size_t position) const
{
out << std::string(position, ' ') << "MyClass " << i << std::endl;
}
};
int main()
{
Document document;
document.objects.emplace_back(MyClass{1});
document.objects.emplace_back(document);
document.objects.emplace_back(MyClass{2});
document.draw(std::cout, 0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment