第一种: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;
-----------------------------------------------------------------------------------------------------
记录,供参考。