effective c++条款 31 实践:

要点

1 前向声明,减少头文件依赖;
    1 背后的思想是,头文件尽量自己处理依赖,万一做不到,让他与其他文件类的
    声明式相依.做到实现与定义分离
    2 但有限制: 前向声明的类不能定义对象. 因为编译器需要知道类的大小,如果类作为类成员
    是要计大小的.
    3 1 指针 引用的成员ok,作为形参或返回值ok
2. pimple模式,桥接模式,而且桥接的是自己的实现
    Person又叫Handle class.
3. 另外的实现类似的设计方法是,抽象类

Date,Person,PersonImpl Date:

//Date.h
class Date {
public:
    Date(int m);
    int get_m();
    void set_m(int m);
private:
    int _m;
};
//Date.cpp
#include "Date.h"

Date::Date(int m): _m(m)
{
}

int Date::get_m()
{
    return _m;
}

void Date::set_m(int m)
{
    this->_m = m;
}

Person:

//Person.h
#include <iostream>
#include <memory>

//#include "PersonImpl.h"
/*
 * 使用前像声明,不依赖头文件后,改动PersonImle,Date 都不影响Person,
 * Person不用重新编译.
 * 接口与实现分离的重要思想
 */
class PersonImple;
class Date;

class Person {
public:
    Person()=default;
    Person(const std::string & name, const Date & date);
    //真正的实现放在PsersonImple里 point to implementation ,即pimple模式
    const std::string getDate();
    const std::string getName();
//Person.cpp
#include <sstream>
#include "Person.h"
#include "PersonImpl.h"


Person::Person(const std::string & name, const Date & date)
{
    pImpl = std::make_shared<PersonImple>(name, date);
}

const std::string Person::getDate()
{
    std::ostringstream sout;
    auto date = pImpl->getDate();
    sout << date.get_m();
    return sout.str();
}

PersonImpl:

//PersonImpl.h
#include <iostream>
#include <memory>

#include "Date.h"

class PersonImple {
public:
    PersonImple(const std::string & name, const Date & date);
    const Date getDate();
    const std::string getName();
private:
    std::string _name;
    Date _date;
};
//PersonImpl.cpp
#include "PersonImpl.h"

PersonImple::PersonImple(const std::string & name, const Date & date): _name(name),_date(date){}

const Date PersonImple::getDate(){
    return this->_date;
}
const std::string PersonImple::getName(){
    return this->_name;
}