Skip to content

Instantly share code, notes, and snippets.

@allyourcode
Created August 29, 2013 00:03
Show Gist options
  • Select an option

  • Save allyourcode/6372877 to your computer and use it in GitHub Desktop.

Select an option

Save allyourcode/6372877 to your computer and use it in GitHub Desktop.
pimpl C++ design pattern. main.cc has the definition of class K, but not that of K::Impl. test.cc has the definition of K::Impl (as well as that of K); thus, it has access to all of the internals without resorting to such hacks as friend. Besides testability, another benefit is that move semantics can be implemented very easily. In fact, I can't…
#include "lib.h"
#include <stdio.h>
class K::Impl {
public:
Impl(int i) : i_(i) {}
virtual ~Impl() {}
virtual int i() const {
printf("getter: %d\n", i_);
return i_;
}
virtual void set_i(int i) {
printf("setter\n");
i_ = i;
}
int i_;
};
K::K(int i) : self_(new Impl(i)) {}
K::K(K&& source)
: self_(source.self_) {
source.self_ = nullptr;
}
K::~K() { delete self_; }
int K::i() const {
return self_->i();
}
void K::set_i(int i) {
self_->set_i(i);
}
#ifndef LIB_H
#define LIB_H
class K {
public:
class Impl;
K(int i);
K(K&& source);
virtual ~K();
virtual int i() const;
virtual void set_i(int i);
private:
Impl* self_;
};
#endif
#include <stdio.h>
#include "lib.h"
K MakeK() {
printf("MakeK\n");
return K(1);
}
int main() {
K k = MakeK();
k.i();
k.set_i(2);
/*
K k2(100);
k2 = k;
*/
return 0;
}
#include "lib.cc"
#include <assert.h>
#include <stdio.h>
int main() {
K::Impl k(1);
assert(k.i_ == 1);
assert(k.i() == 1);
printf("Constructor works.\n");
k.set_i(2);
assert(k.i_ == 2);
assert(k.i() == 2);
printf("Setter works.\n");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment