基于C++语言开发的库,需要提供给第三方来调用,就必然会涉及到如何设计接口类。一般来说,有两种方法设计接口类,第一种是PIMP方法,即Pointer to Implementation,在接口类成员中包含一个指向实现类的指针,这样可以最大限度的做到接口和实现分离的原则。第二种方法叫Object-Interface方法,它的思想是采用C++的动态功能,实现类继承接口类,功能接口函数定义成虚函数。
PIMP方法
接口类头文件
Person.h文件:
#ifndef PERSON_H
#define PERSON_H
#include <string>
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 <string>
class PersonImpl {
public:
PersonImpl(std::string& name);
virtual ~PersonImpl();
std::string& getName();
private:
std::string m_name;
};
#endif
PersonImpl.cpp:
#include "PersonImpl.h"
#include <string>
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 <iostream>
#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 <string>
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 <iostream>
#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 <iostream>
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 <iostream>
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 <iostream>
#include "./Person.h"
using namespace std;
int main()
{
string name("hank");
Person *p = createPerson(FEMALE, name);
cout << "Name: " << p->getName() << endl;
return 0;
}
网友评论