Skip to content

Instantly share code, notes, and snippets.

@bassosimone
Last active August 29, 2015 14:16
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 bassosimone/683bdce621b85aadae84 to your computer and use it in GitHub Desktop.
Save bassosimone/683bdce621b85aadae84 to your computer and use it in GitHub Desktop.
#include <ight/common/pointer.hpp> // SharedPointer: a std::shared_ptr wrapper with null pointer checks
using namespace ight::common::pointer; // Allow you to use SharedPointer directly
// An abstract class and two implementations of it
struct AbstractAntani {
// API:
virtual void foo() = 0;
virtual std::string bar(double) = 0;
virtual ~AbstractAntani() = 0;
// No copy and no move
AbstractAntani(AbstractAntani&) = delete;
AbstractAntani& operator=(AbstractAntani&) = delete;
AbstractAntani(AbstractAntani&&) = delete;
AbstractAntani& operator=(AbstractAntani&&) = delete;
}
struct SpecificAntani : public AbstractAntani {
virtual void foo() {}
virtual std::string bar(double) { return "xx" };
virtual ~SpecificAntani() {}
}
struct AnotherAntani : public AbstractAntani {
virtual void foo() {}
virtual std::string bar(double) { return "x" };
virtual ~SpecificAntani() {}
}
// Proxy pattern case #1
// 1) you need to write more code (-)
// 2) you have a factory like constructor (-)
// 3) but usage is more intuitive (+)
class Antani {
SharedPointer<AbstractAntani> impl;
public:
Antani(std::map<std::string, std::string> options) {
if (options["type"] == "specific") {
impl = std::make_shared<SpecificAntani>();
} else {
impl = std::make_shared<AnotherAntani>();
}
}
virtual void foo() { impl->foo(); }
virtual std::string bar(double) { return impl->bar(); };
virtual ~SpecificAntani() { /* nothing */; }
}
Antani foo{{"type", "specific"}};
foo.foo();
foo.bar();
// Proxy pattern case #2
// 1) you write less code (+)
// 2) construction is more verbose (-)
// 3) usage is through a pointer (-)
SharedPointer<AbstractAntani> foo = std::make_shared<AnotherAntani>();
foo->foo();
foo->bar();
// 4) in the following case (and this is a bug of my
// implementation) you get a pointer without automatic
// null pointer check
auto foo = std::make_shared<AnotherAntani>();
// The above problem could be fixed in the following two ways:
// A) add a make method to the wrapped pointer
auto foo = SharedPointer<AnotherAntani>(); // Empty shared pointer with null pointer checks
auto foo = SharedPointer<AnotherAntani>::make(); // Pointer to something
// B) more dangerous but more intuitive, you allow to set the pointer directly
auto foo = SharedPointer<AbstractAntani>();
foo = new AnotherAntani();
// C) same as B but using a standard method in C++'s shared_ptr
auto foo = SharedPointer<AbstractAntani>();
foo.reset(new AnotherAntani());
// Proxy pattern case #3:
// See https://gist.github.com/bassosimone/ebaf789cea61c11efb67
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment