C++创建稳定的接口-PImpl

C++的PImplidiom是一种用于隔离类的公共接口和私有实现的技术,通过引入接口类和实现类来保持接口的稳定性。这种方法使得修改类的内部实现而不影响客户端代码成为可能,减少了重新编译的需求。示例展示了如何使用智能指针实现PImpl模式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++创建稳定的接口-PImpl

c++语言本质上对抽象的原则不太友好,语法要求将public接口和private(或protected)数据成员及方法放在一个类定义中。从而将类的某些内部实现细节向客户公开。这种做法的缺点在于,如果不得不在类中加入新的非public方法或者数据成员,所有的客户代码都将必须重新编译,这对于大型项目来说非常的浪费时间。

不过好消息是这种问题可以被避免。可以创建清晰的接口,并隐藏所有实现细节,从而得到稳定的接口。坏消息是这样做有点复杂。基本原则是为想编写的每个类都定义两个类,接口类和实现类。实现类与不采用这种方法编写的类相同,接口类给出与实现类一样的public方法,但只有一个数据成员,指向实现类对象的一个指针。这被称为pimpl idiom或bridge模式,接口类方法的实现只是调用实现类对象的等价方法。这样做的结果就是无论实现如何改变,都不会影响public接口类,从而降低了重新编译的可能。

当且只有实现改变时,使用接口类的客户不需要重新编译。注意只有在单个数据成员是实现类的指针时,这个方法才有效。如果他是按值传递的数据成员,在实现类的定义改变时,客户代码必须重新编译。

代码示例:

Foo.h

#include <iostream>
#include <memory>
using namespace std;

// 接口类
class Foo
{
public:
    Foo();
    Foo(int n);
    void print();

private:
    class Impl;
    unique_ptr<Impl> m_impl;
};

Foo.cpp


#include "Foo.h"

using namespace std;

// 实现类
class Foo::Impl
{
public:
    void print()
    {
        cout << "hello" << endl;
    }

    Impl(int n) : m_n(n) { cout << "impl(int n)" << endl; }

private:
    int m_n;
};

Foo::Foo(int n) : m_impl{make_unique<Impl>(n)} {};
void Foo::print()
{
    m_impl->print();
}

int main()
{
    Foo foo(10);
    foo.print();

    return 0;
}

为了实现与接口分离,另一种方法是使用抽象接口及实现该接口的实现类,抽象接口时只有纯虚方法的接口。

参考连接:PImpl - cppreference.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值