Skip to content

Instantly share code, notes, and snippets.

@sherm1
Last active August 29, 2015 14:05
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save sherm1/a457a94a7a37c945a4c5 to your computer and use it in GitHub Desktop.
Save sherm1/a457a94a7a37c945a4c5 to your computer and use it in GitHub Desktop.
Demonstration of ClonePtr in an std::map
// 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() <<
" (" << 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;
}
# 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})
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)
----------
@sherm1
Copy link
Author

sherm1 commented Aug 11, 2014

Hi, @chrisdembia -- check out this ClonePtr example.

@chrisdembia
Copy link

Hmm, unfortunately, it seems like @mentions don't work in gistland.

@sherm1
Copy link
Author

sherm1 commented Aug 11, 2014

I didn't get an email notification about your post either! And I don't see a "follow" option 👎. At least emojis work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment