// Demonstrate use of ClonePtr to allow deep copying of maps containing // abstract objects. #include "Simbody.h" #include #include #include #include using namespace SimTK; using namespace std; class AbstractBase { public: AbstractBase(const string& name) : m_name(name) {} virtual ~AbstractBase() {} virtual AbstractBase* clone() const = 0; virtual std::string getType() const = 0; string getNameAndAddress() const { return m_name + "\tis a " + getType() + "@" + String((size_t)this, "0x%llx"); } private: string m_name; }; class Foo : public AbstractBase { public: Foo(const string& name) : AbstractBase(name) {} Foo* clone() const override {printf("cloning Foo\n"); return new Foo(*this);} string getType() const override {return "Foo";} }; class Bar : public AbstractBase { public: Bar(const string& name) : AbstractBase(name) {} Bar* clone() const override {printf("cloning Bar\n"); return new Bar(*this);} string getType() const override {return "Bar";} }; using Map=map>; int main() { Map stuff; stuff["Foo1"] = new Foo("Foo1"); stuff["Foo2"] = new Foo("Foo2"); stuff["MyBar"] = new Bar("MyBar"); stuff["YourBar"] = new Bar("YourBar"); for (auto& p : stuff) cout << p.first << ": " << p.second->getNameAndAddress() << " (" << typeid(*p.second).name() << ")" << endl; Map copy(stuff); // "copy" should be a deep copy of "stuff" now. for (auto& p : copy) cout << p.first << ": " << p.second->getNameAndAddress() << " (" << typeid(*p.second).name() << ")" << endl; return 0; }