Effective C++条款31 将文件间的编译依存关系降至最低的2种实现方法

第一种:Handle class(impl idiom),关键点是运用指针隐藏类的实现部分,#include的只是一个公共接口。下面以Person为例,Person是一个接口类,ImplPerson是接口的实现类,Person类中有一个指针指向ImplPerson类,达到对实现部分隐藏的作用:

//Person.h文件

#ifndef ARTICLE31_PERSON_H_
#define ARTICLE31_PERSON_H_
#include <string>
#include <memory>
#include <utility>

namespace Article31 {

class Person {
public:
    explicit Person(const std::string&, int, const std::string&);
    const std::pair<std::string, std::pair<int, std::string>> PersonInfo() const;
private:
    class ImplPerson; //将类声明为私有的类中类
    std::shared_ptr<ImplPerson> pPerson; //这个语句式关键,隐藏类的实现
};

} /* namespace Article31 */

#endif /* ARTICLE31_PERSON_H_ */

-------------------------------------------------------------------------------------------------------------------------------

//Person.cpp 类的实现部分

#include "Person.h"

namespace Article31 {

} /* namespace Article31 */

Article31::Person::Person(const std::string& n, int a,
        const std::string& addr) : pPerson(std::make_shared<ImplPerson>(n, a, addr)) {
}

//注意,此处是Person类的类中类,即Person的实现类ImplPerson
class Article31::Person::ImplPerson {
public:
    explicit ImplPerson(const std::string&, int, const std::string&);
    const std::string get_name() const {return name;}
    const int get_age() const {return age;}
    const std::string get_address() const {return address;}
private:
    std::string name;
    int age;
    std::string address;
};

Article31::Person::ImplPerson::ImplPerson(const std::string& n, int a,
        const std::string& addr) : name(n), age(a), address(addr) {
}


const std::pair<std::string, std::pair<int, std::string> > Article31::Person::PersonInfo() const {
    std::pair<int, std::string> p1(pPerson->get_age(), pPerson->get_address());
    std::pair<std::string, std::pair<int, std::string>> pinfo(pPerson->get_name(), p1);
    return pinfo;
}

---------------------------------------------------------------------------------------

  main.cpp中的调用代码

Article31::Person P("AAA", 44, "重庆市");
std::cout<<P.PersonInfo().first<<" "<<P.PersonInfo().second.first<<" "<<P.PersonInfo().second.second<<std::endl;

----------------------------------------------------------------------------------------

第2种实现:Interface class 基于abstract class(抽象基类)与derived class(派生类)的思想,运用动态绑定技术将接口与实现分离,关键点3条:(1)定义abstract class基类,abstract class最佳方式是只包括:虚析构函数,纯虚函数,不要包括类数据成员;(2)定义继承自abstract class基类的derived class(派生类),实现各个接口;(3)在abstract class基类中增加一个public的static成员,建议名字为create函数(工厂模式),运用指针创建对象,返回一个指针。以Person为例,实现代码如下:

BasePerson.h //abstract class基类声明

#ifndef ARTICLE31_BASEPERSON_H_
#define ARTICLE31_BASEPERSON_H_
#include <string>
#include <map>
#include <memory>

namespace Article31 {

class Base_Person {
public:
    virtual const std::string get_name() const = 0;
    virtual const std::pair<int, std::string> get_info() const = 0;
    virtual ~Base_Person(){}
    static std::shared_ptr<Base_Person> create(const std::string&, int, const std::string&); //关键点(3)
};

} /* namespace Article31 */

#endif /* ARTICLE31_BASEPERSON_H_ */

---------------------------------------------------------------------------

BasePerson.cpp

#include "BasePerson.h"
#include "DerivedPerson.h"

namespace Article31 {

} /* namespace Article31 */

//关键点(3)的实现
std::shared_ptr<Article31::Base_Person> Article31::Base_Person::create(
        const std::string& n, int i, const std::string& addr) {
    return std::make_shared<Article31::Derived_Person>(n, i ,addr);
}

------------------------------------------------------------------------------------------------------

//派生类声明

DerivedPerson.h

#ifndef ARTICLE31_DERIVEDPERSON_H_
#define ARTICLE31_DERIVEDPERSON_H_

#include "BasePerson.h"

namespace Article31 {

class Derived_Person: public Base_Person {
public:
    Derived_Person(const std::string &, int, const std::string&);
    virtual const std::string get_name() const;
    virtual const std::pair<int, std::string> get_info() const;
    virtual ~Derived_Person(){}
    void printage(const int& i);
    void printage(int& i);
private:
    std::string name;
    int age;
    std::string address;
};

} /* namespace Article31 */

#endif /* ARTICLE31_DERIVEDPERSON_H_ */


-----------------------------------------------------------------------

//派生类实现

//DerivedPerson.cpp

#include "DerivedPerson.h"

namespace Article31 {

} /* namespace Article31 */

Article31::Derived_Person::Derived_Person(const std::string& n,
        int a, const std::string& addr) : name(n), age(a), address(addr) {
}

const std::string Article31::Derived_Person::get_name() const {
    return name;
}

const std::pair<int, std::string> Article31::Derived_Person::get_info() const {
    return std::pair<int, std::string>(age, address);
}


-------------------------------------------------------------------------------------------------

//main.cpp调用

    std::shared_ptr<Article31::Base_Person> bp = Article31::Base_Person::create("BBB", 42, "重庆市");
    std::cout<<bp->get_name()<<" "<<bp->get_info().first<<" "<<bp->get_info().second<<std::endl;

-----------------------------------------------------------------------------------------------------

记录,供参考。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值