美文网首页
如何设计C++接口类

如何设计C++接口类

作者: crazyhank | 来源:发表于2019-10-06 20:12 被阅读0次

    基于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;
    }
    

    相关文章

      网友评论

          本文标题:如何设计C++接口类

          本文链接:https://www.haomeiwen.com/subject/xtiypctx.html