2019-10-09

于C++语言开发的库,需要提供给第三方来调用,就必然会涉及到如何设计接口类。一般来说,有两种方法设计接口类,第一种是PIMP方法,即Pointer to Implementation,在接口类成员中包含一个指向实现类的指针,这样可以最大限度的做到接口和实现分离的原则。第二种方法叫Object-Interface方法,它的思想是采用C++的动态功能,实现类继承接口类,功能接口函数定义成虚函数。

PIMP方法

接口类头文件

Person.h文件:

#ifndef PERSON_H#define PERSON_H#include class PersonImpl; //实现类的声明,这里不需要暴露实现细节class Person {public:    Person(std::string& name);    virtual ~Person();    std::string& getName();//要暴露的功能接口private:    PersonImpl *m_personImpl;//指向实现类的对象};#endif

接口类的实现文件

Person.cpp:

#include "Person.h"#include "PersonImpl.h"Person::Person(std::string& name){    m_personImpl = new PersonImpl(name);//在接口类的构造函数中生成一个实现类对象}Person::~Person(){    if (m_personImpl) {        delete m_personImpl;    }}std::string& Person::getName(){    return m_personImpl->getName();//真正调用的是实现类的功能接口}

实现类的代码

PersonImpl.h:

#ifndef PERSON_IMPL_H#define PERSON_IMPL_H#include class PersonImpl {public:    PersonImpl(std::string& name);    virtual ~PersonImpl();    std::string& getName();private:    std::string m_name;};#endif

PersonImpl.cpp:

#include "PersonImpl.h"#include PersonImpl::PersonImpl(std::string& name){    m_name = name;}PersonImpl::~PersonImpl(){}std::string& PersonImpl::getName(){    return m_name;}

我们可以将这些代码编译成一个动态库:

$g++ -fPIC -shared -o libperson.so Person.cpp PersonImpl.cpp

我们可以写一个测试程序,调用刚刚编译好的动态库:

#include #include "./Person.h"using namespace std;int main(){    string name("hank");    Person p(name);    cout << "Name: " << p.getName() << endl;    return 0;}

Object-Interface方法

一般来说,如果一个接口类对应有若干个实现类,可以采用这种方法。

接口类头文件

Person.h:

#ifndef PERSON_H#define PERSON_H#include class Person {public:    Person();    virtual ~Person();    virtual std::string& getName() = 0;//纯虚函数,保证了调用者不会基于接口类进行实例化操作。};enum GENDER {//定义了性别属性,用于区分不同的实现类对象    MALE,    FEMALE};Person* createPerson(GENDER gender, std::string& name);//全局函数,用于创建不同的实现类对象。#endif

接口类实现

Person.cpp:

#include #include "Person.h"#include "Male.h"#include "Female.h"Person::Person(){}Person::~Person(){}Person* createPerson(GENDER gender, std::string& name){    Person* p;    switch (gender) {        case MALE:            p = new Male(name);            break;        case FEMALE:            p = new Female(name);            break;        default:            std::cout << "wrong gender!" << std::endl;            return NULL;    }    return p;}

实现类

(1)Male类

Male.h:

#ifndef MALE_H#define MALE_H#include "Person.h"class Male : public Person {public:    Male(std::string& name);    virtual ~Male();    std::string& getName();private:    std::string m_name;};#endif

Male.cpp:

#include "Male.h"#include Male::Male(std::string& name){    m_name = name;}Male::~Male(){}std::string& Male::getName(){    std::cout << "In Male::getName" << std::endl;    return m_name;}

(2)Female类

Female.h:

#ifndef FEMALE_H#define FEMALE_H#include "Person.h"class Female : public Person {public:    Female(std::string& name);    virtual ~Female();    std::string& getName();private:    std::string m_name;};#endif

Female.cpp:

#include "Female.h"#include Female::Female(std::string& name){    m_name = name;}Female::~Female(){}std::string& Female::getName(){    std::cout << "In Female::getName" << std::endl;    return m_name;}

测试程序

main.cpp:

#include

#include "./Person.h"

using namespace std;

int main()

{

    string name("hank");

    Person *p = createPerson(FEMALE, name);

    cout << "Name: " << p->getName() << endl;

    return 0;

你可能感兴趣的:(2019-10-09)