I've been trying to have a go at a 'pimpl' idiom but I just can't get the darned thing to compile.
On Linux Mint with g++ v. 4.6.3 I get the following error:
$ g++ main.cc
/tmp/ccXQ9X9O.o: In function `main':
main.cc:(.text+0xd7): undefined reference to `Person::Person(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)'
collect2: ld returned 1 exit status
This is my code:
person.hh
#ifndef PERSON_HH
#define PERSON_HH
#include <tr1/memory>
#include <string>
class Person
{
private:
class PersonImpl;
std::tr1::shared_ptr<PersonImpl> pImpl;
public:
Person(const std::string& name, int age=0);
~Person();
const std::string& get_name() const;
int get_age() const;
};
#endif
person.cc
#include <string>
#include "person.hh"
class Person::PersonImpl
{
public:
std::string name;
int age;
PersonImpl(const std::string& n, int a) : name(n), age(a) {}
};
Person::Person(const std::string& name, int age) : pImpl(new PersonImpl(name, age)) {}
Person::~Person() {}
const std::string& Person::get_name() const { return pImpl->name; }
int Person::get_age() const { return pImpl->age; }
main.cc
#include <iostream>
#include "person.hh"
int main()
{
const std::string name = "foo";
Person p(name, 50);
return 0;
}
Apart from the code mistakes, could you please advise on the approach I've taken to mimicking a 'pimpl' idiom? Does this conform to it?
The problem seems to be due to the fact that your person.cc
file is not being linked in. You may have to adjust your project configuration to fix this.
Apart from the code mistakes, could you please advise on the approach I've taken to mimicking a 'pimpl' idiom? Does this conform to it?
I would suggest using unique_ptr
rather than shared_ptr
, since the PersonImpl
implementation object is owned exclusively by the Person
object:
class Person
{
private:
class PersonImpl;
std::tr1::unique_ptr<PersonImpl> pImpl;
// ^^^^^^^^^^
// ...
};
Apart from this, you should make use of constructor initialization lists to initalize the pImpl
data member:
Person::Person(const std::string& name, int age)
: pImpl(new PersonImpl(name, age))
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{
}