C++ Pimpl 惯用模式

介绍:

       Pimpl idiom意为“pointer to imprementation”,即指向实现的指针,这样方法是把某个类分割成两个classes,一个只提供接口,另一个负责实现该接口,这样便实现了接口与实现分离,这个分离方式的关键在于以“声明的依存性”替换“定义的依存性”,从而达到编译依存性最小化的目的。可以说Pimpl是C++的一种惯用模式。

实现:

         PIMPL基于这样一个事实:在C++类中,允许定义一个成员指针,指向一个已声明过的类型。在头文件中只是存放该类型的声明,而具体的定义是存放在CPP文件中,这样就可以隐藏类型的具体实现。

 

例子:

Book.h文件:

#ifndef BOOK_H_
#define BOOK_H_
#include <iostream>
#include <memory>
// 这是一个声明文件,作为接口类,这样不管BookImpl类的实现怎么修改都不影响接口的使用
class Book{
public:
    Book(std::string name, std::string author);
    ~Book();
    Book(const Book& b);
    Book& operator=(const Book& b);
    void print();
private:
    class BookImpl; // Book实现类的前置声明,Book的内嵌类
    std::shared_ptr<BookImpl> mp_impl;
};
#endif

BookPimpl文件:

#ifndef BOOK_PIMPL_H__
#define BOOK_PIMPL_H__
#include "Book.h"
// 这是一个定义类,具体实现在cpp中,不需要提供给客户,达到与声明类分离
// BookImpl在Book类了进行了前置声明,相对于是Book类的内嵌类
class Book::BookImpl {
public:
    BookImpl(std::string name, std::string author);
    ~BookImpl();
    void print();
private:
    std::string m_title;
    std::string m_author;
};
#endif

Book.cpp文件:

#include "Book.h"           // 需要实现Book.h类
#include "BookPimpl.h"      // 需要调用BookPimpl的成员函数
#include <string>
Book::Book(std::string name, std::string author):mp_impl(new BookImpl(name, author)) {
}
Book::~Book() {}
Book::Book(const Book& b) {}
Book& Book::operator=(const Book& b) {
    return *this;
}
void Book::print() {
    mp_impl->print();
}
Book::BookImpl::BookImpl(std::string name, std::string author) {
    m_title = name;
    m_author = author;
}
Book::BookImpl::~BookImpl() {}
void Book::BookImpl::print() {
    std::cout << "book title " << m_title << " book author " << m_author << std::endl;
}

Main.cpp文件

#include "Book.h"
int main(int argc, char* argv[]) {
    Book book("C++", "sampson");
    book.print();
    return 0;
}

这样,Book作为声明类,BookPimpl作为定义类,具体的实现放在BookPimpl类中通过cpp文件实现,客户只需要拿到Book.h文件即可,不用关心具体的实现。当具体实现发生修改时也不需要重新编译客户代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值