Reputation: 38919
I pursued the PImpl design to avoid having to export STL from my dynamic library.
Old:
//In header file
class Foo{
public:
const map<char, char>& getMap() {return _map;}
private:
map<char, char> _map;
};
New:
//In header file
class Foo{
public:
Foo();
~Foo();
const map<char, char>& getMap();
private:
struct Impl;
Impl* _pimpl;
};
//In implementation file
struct Foo::Impl{
map<char, char> _map;
}
Foo::Foo(): _pimpl(new Impl){}
Foo::~Foo(){delete _pimpl;}
const map<char, char>& Foo::getMap(){return _pimpl->_map;}
However the clear issue is that I still have to export the map
as part of my library. I don't want to stop returning STL, but I don't see a way around it. Is there another paradigm which will still let me return STL but not have to export it?
Upvotes: 1
Views: 154
Reputation: 227418
A solution is to not use std::map
in the interface of your class, but rather, implement the requires subset of methods. For example, assuming you want read-write element access via operator[]
,
// Foo.h
class Foo{
public:
Foo();
~Foo();
const char& operator[](char key) const;
char& operator[](char key);
private:
struct Impl;
Impl* _pimpl;
};
then
// Foo.cpp
#include <map>
struct Foo::Impl
{
std::map<char, char> _map;
};
Foo::Foo() : _pimpl(new Impl){}
Foo::~Foo(){delete _pimpl;} // don't forget to take care of copy and assignment
const char& Foo::operator[](char key) const {return _pimpl->_map[key];}
char& Foo::operator[](char key) {return _pimpl->_map[key];}
Upvotes: 1