• 6.3 Case Studies - PIMPL


    demo_pimpl_A.hpp

    // demo_pimpl_A.hpp
    
    // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
    // Use, modification and distribution is subject to the Boost Software
    // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
    // http://www.boost.org/LICENSE_1_0.txt)
    
    // class whose declaration is hidden by a pointer
    struct B;
    
    struct A {
        // class a contains a pointer to a "hidden" declaration
        B *pimpl;
        template<class Archive>
        void serialize(Archive & ar, const unsigned int file_version);
        A();
        ~A();
    };
    
    #endif // BOOST_SERIALIZATION_EXAMPLE_DEMO_PIMPL_A_HPP
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在这段文本中,有一个名为demo_pimpl.cpp的程序,用来演示如何使用PIMPL。文件demo_pimpl_A.hpp包含了一个类A的声明,该类通过包含一个指向结构体B的指针来隐藏其实现细节。但是,B的具体定义在另一个单独编译的模块demo_pimpl_A.cpp中。

    demo_pimpl_A.cpp

    // demo_pimpl_A.cpp
    #include 
    #include 
    
    #include "demo_pimpl_A.hpp"
    
    // "hidden" definition of class B
    struct B {
        int b;
        template<class Archive>
        void serialize(Archive & ar, const unsigned int /* file_version */){
            ar & b;
        }
    };
    
    A::A() :
        pimpl(new B)
    {}
    A::~A(){
        delete pimpl;
    }
    // now we can define the serialization for class A
    template<class Archive>
    void A::serialize(Archive & ar, const unsigned int /* file_version */){
        ar & pimpl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    这种设计的优势包括:
    1.类型B可以在不包含其头文件的情况下使用。
    2.类型B的实现可以更改而不会引发大规模的重新编译。

    然而,在链接时,会出现错误,因为两个符号未定义:

    void A::serialize(boost::archive::text_oarchive & ar, const unsigned int file_version);
    void A::serialize(boost::archive::text_iarchive & ar, const unsigned int file_version);
    
    • 1
    • 2

    问题在于,在编译上述代码时,serialize模板没有被实例化,因为不知道要与哪种类型的归档一起使用。因此,在尝试链接时,这些函数会“丢失”。解决方法是显式实例化将要使用的归档类型的序列化代码。在示例中,通过在任何*.cpp文件中包含以下代码来实现:

    // without the explicit instantiations below, the program will
    // fail to link for lack of instantiantiation of the above function
    // note: the following failed to fix link errors for vc 7.0 !
    template void A::serialize<boost::archive::text_iarchive>(
        boost::archive::text_iarchive & ar, 
        const unsigned int file_version
    );
    template void A::serialize<boost::archive::text_oarchive>(
        boost::archive::text_oarchive & ar, 
        const unsigned int file_version
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    这样,程序就能够成功链接。不过,这种方法的缺点是必须事先知道要与隐藏的序列化一起使用哪些归档类型,因为它依赖于显式实例化模板,而这可能会导致平台依赖性。

    demo_pimpl.cpp

    // demo_pimpl.cpp
    #include 
    
    #include 
    #include 
    
    #include "demo_pimpl_A.hpp"
    
    int main(int argc, char* argv[])
    {
        std::stringstream ss;
    
        const A a;
        {
            boost::archive::text_oarchive oa(ss);
            oa << a;
        }
        A a1;
        {
            boost::archive::text_iarchive ia(ss);
            ia >> a1;
        }
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
  • 相关阅读:
    使用Spring WebFlux和Spring Cloud的反应式微服务
    解决 @RefreshScope 导致定时任务注解 @Scheduled 失效
    20231012_python练习_服务端与客户端数据交互v2_增加xlsx表格数据批量导入数据库
    FTP 文件传输协议:概念、工作原理;上传下载操作步骤
    C/C++ 如何调用Lua脚本,C/C++与 Lua的交互
    外设驱动库开发笔记48:MCP4725单通道DAC驱动
    学习Vue的入门方法有哪些呢?
    LeetCode 剑指 Offer 10- I. 斐波那契数列
    预告|年度总决赛即将打响, 20余个项目角逐嘉兴经开区
    JavaScript 64 JavaScript 函数 64.1 JavaScript 函数定义
  • 原文地址:https://blog.csdn.net/qq_40178082/article/details/133208464