Inheritance is the base class of evil (Sean Parent)

来源:互联网 发布:1光年等于多少米的算法 编辑:程序博客网 时间:2024/05/20 06:26
#include <iostream>
#include <vector>
#include <string>
#include <memory>
#include <cassert>

using namespace std;

template<typename T>
void draw(const T& x, ostream& out, size_t pos) {
    out << string(pos, ' ') << x << "\n";
}

class object_t {
public:
    template<typename T>
    object_t(T x) : self_(make_shared<model<T>>(move(x))) {
        cout << "ctor\n";
    }

    friend void draw(const object_t& x, ostream& out, size_t pos) {
        x.self_->draw_(out, pos);
    }

private:
    struct concept_t {
        virtual ~concept_t() = default;
        virtual void draw_(ostream&, size_t) const = 0;
    };

    template<typename T>
    struct model: concept_t {
        model(T x) : data_(move(x)) {
        }

        void draw_(ostream& out, size_t pos) const {
            draw(data_, out, pos);
        }

        T data_;
    };

private:
    shared_ptr<const concept_t> self_;
};

using document_t = vector<object_t>;

class my_class_t {
};

void draw(const my_class_t&, ostream& out, size_t pos) {
    out << string(pos, ' ') << "my_class_t\n";

}

void draw(const document_t& x, ostream& out, size_t pos) {
    out << string(pos, ' ') << "<document>\n";
    for (const auto& e: x) {
        draw(e, out, pos + 2);
    }
    out << string(pos, ' ') << "</document>\n";
}

using history_t = vector<document_t>;
void commit(history_t& x) {
    assert(!x.empty());
    x.push_back(x.back());
}

void undo(history_t& x) {
    assert(!x.empty());
    x.pop_back();
}

document_t& current(history_t& x) {
    assert(!x.empty());
    return x.back();
}

int main() {
    history_t h(1);
    current(h).emplace_back(0);
    current(h).emplace_back(string("hello"));
    draw(current(h), cout, 0);
    cout << "-----------------------\n";

    commit(h);

    current(h).emplace_back(current(h));
    current(h).emplace_back(my_class_t());
    cout << "change hello\n";
    current(h)[1] = string("world");

    draw(current(h), cout, 0);
    cout << "-----------------------\n";

    undo(h);

    draw(current(h), cout, 0);

    return 0;
}

原创粉丝点击