Code to demo Item 31 in Effective C++
Souce code list.
Address.h
Date.h
PersonImpl.h
PersonImpl.cpp
Person.h
Person.cpp
main.cpp
Compile and run:
g++ -c PersonImpl.cpp
g++ -c Person.cpp
g++ *.o -o run
./run
One thing worth of mention is Person.cpp. If I have include Address.h before PersonImpl.h, the following error will show up:
field ‘theAddress’ has incomplete type
The reason is that PersonImpl needs Address to be compiled. So Address defintion must occurs textually before PersonImpl definition. At this point, C++ is different from Java. In Java, textual layout is unimportant in most of situations.
Address.h
class Address {
};
Date.h
class Date {
};
PersonImpl.h
#include <string>
#include <tr1/memory>
using namespace std;
class Date;
class Address;
class PersonImpl {
public:
PersonImpl(const string& name, const Date& birthday, const Address& addr);
string name() const;
Date birthday() const;
Address address() const;
private:
string theName;
Date theBirthDate;
Address theAddress;
};
PersonImpl.cpp
#include <string>
#include <iostream>
using namespace std;
#include "Date.h"
#include "Address.h"
#include "PersonImpl.h"
PersonImpl::PersonImpl(const string& name, const Date& birthday, const Address& addr)
: theName(name), theBirthDate(birthday), theAddress(addr) {
}
string PersonImpl::name() const {
return theName;
}
Date PersonImpl::birthday() const {
return theBirthDate;
}
Address PersonImpl::address() const {
return theAddress;
}
Person.h
#include <string>
#include <tr1/memory>
using namespace std;
class PersonImpl;
class Date;
class Address;
class Person {
public:
Person(const string& name, const Date& birthday, const Address& addr);
string name() const;
Date birthday() const;
Address address() const;
private:
tr1::shared_ptr<PersonImpl> pImpl;
};
Person.cpp
#include "Date.h"
#include "Address.h"
#include "Person.h"
#include "PersonImpl.h"
Person::Person(const string& name, const Date& birthday, const Address& addr)
: pImpl(new PersonImpl(name, birthday, addr)) {
}
string Person::name() const {
return pImpl->name();
}
Date Person::birthday() const {
return pImpl->birthday();
}
Address Person::address() const {
return pImpl->address();
}
main.cpp
#include <iostream>
using namespace std;
#include "Date.h"
#include "Address.h"
#include "Person.h"
int main(int argc, const char *argv[]) {
string name = "yaojg";
Date d;
Address addr1;
Person p(name, d, addr1);
cout << "here we go" << endl;
return 0;
}
Compile and run:
g++ -c PersonImpl.cpp
g++ -c Person.cpp
g++ *.o -o run
./run
One thing worth of mention is Person.cpp. If I have include Address.h before PersonImpl.h, the following error will show up:
field ‘theAddress’ has incomplete type
The reason is that PersonImpl needs Address to be compiled. So Address defintion must occurs textually before PersonImpl definition. At this point, C++ is different from Java. In Java, textual layout is unimportant in most of situations.