Skip to content

Instantly share code, notes, and snippets.

@sherm1
Last active August 29, 2015 14:05
Show Gist options
  • Select an option

  • Save sherm1/a457a94a7a37c945a4c5 to your computer and use it in GitHub Desktop.

Select an option

Save sherm1/a457a94a7a37c945a4c5 to your computer and use it in GitHub Desktop.

Revisions

  1. sherm1 revised this gist Aug 11, 2014. 1 changed file with 18 additions and 0 deletions.
    18 changes: 18 additions & 0 deletions Output
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,18 @@
    Here is the output I got from this in Visual Studio 2013.
    Note that all the concrete objects have different addresses,
    showing that a deep copy of the map was done.

    ----------
    Foo1: Foo1 is a Foo@0x14a350 (class Foo)
    Foo2: Foo2 is a Foo@0x14ada0 (class Foo)
    MyBar: MyBar is a Bar@0x14ae10 (class Bar)
    YourBar: YourBar is a Bar@0x14ae80 (class Bar)
    cloning Foo
    cloning Foo
    cloning Bar
    cloning Bar
    Foo1: Foo1 is a Foo@0x14afd0 (class Foo)
    Foo2: Foo2 is a Foo@0x14af60 (class Foo)
    MyBar: MyBar is a Bar@0x14b040 (class Bar)
    YourBar: YourBar is a Bar@0x14b0b0 (class Bar)
    ----------
  2. sherm1 revised this gist Aug 11, 2014. 1 changed file with 4 additions and 3 deletions.
    7 changes: 4 additions & 3 deletions cloneptr.cpp
    Original file line number Diff line number Diff line change
    @@ -49,11 +49,12 @@ int main() {
    stuff["YourBar"] = new Bar("YourBar");

    for (auto& p : stuff)
    cout << p.first << ": " << p.second->getNameAndAddress() << endl;
    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() << endl;

    cout << p.first << ": " << p.second->getNameAndAddress() <<
    " (" << typeid(*p.second).name() << ")" << endl;
    return 0;
    }
  3. sherm1 created this gist Aug 11, 2014.
    22 changes: 22 additions & 0 deletions CMakeLists.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,22 @@
    # Generic CMakeLists.txt for making a Simbody-using executable.
    # This shows how to use the provided SimbodyConfig.cmake to locate a Simbody
    # installation on your machine so you can use it from your own code.
    # You will most likely want to copy some of these lines into your own
    # CMakeLists.txt rather than use this one verbatim.
    cmake_minimum_required(VERSION 2.8)
    project(cloneptr)

    # List your source and header files here.
    set(my_source_files cloneptr.cpp)
    set(my_header_files )

    # This depends on SimbodyConfig.cmake being located somewhere predictable
    # on your machine. If you have installed it somewhere that CMake won't be
    # able to guess, you'll need to tell find_package where to look.
    find_package(Simbody REQUIRED)

    include_directories(${Simbody_INCLUDE_DIR})
    link_directories(${Simbody_LIB_DIR})

    add_executable(cloneptr ${my_source_files} ${my_header_files})
    target_link_libraries(cloneptr ${Simbody_LIBRARIES})
    59 changes: 59 additions & 0 deletions cloneptr.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,59 @@
    // Demonstrate use of ClonePtr to allow deep copying of maps containing
    // abstract objects.

    #include "Simbody.h"

    #include <cstdio>
    #include <iostream>
    #include <string>
    #include <map>

    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<string, ClonePtr<AbstractBase>>;
    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() << endl;

    Map copy(stuff); // "copy" should be a deep copy of "stuff" now.
    for (auto& p : copy)
    cout << p.first << ": " << p.second->getNameAndAddress() << endl;

    return 0;
    }