程序结构如下,

本例主要使用std::unique_ptr封装C++常用的pimpl idom,就是在cpp文件中用一个impl来封装细节。实现部分可以随意修改,但是保持接口部分不变。
这样一来是节省编译时间。
二来是隐藏实现到cpp。
程序代码如下,
test/CMakeLists.txt

cmake_minimum_required(VERSION 2.6)if(APPLE)message(STATUS "This is Apple, do nothing.")set(CMAKE_MACOSX_RPATH 1)set(CMAKE_PREFIX_PATH /Users/aabjfzhu/software/vcpkg/ports/cppwork/vcpkg_installed/x64-osx/share )
elseif(UNIX)message(STATUS "This is linux, set CMAKE_PREFIX_PATH.")set(CMAKE_PREFIX_PATH /vcpkg/ports/cppwork/vcpkg_installed/x64-linux/share)
endif(APPLE)project(wrapped_pimpl)set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-narrowing")add_definitions(-g)find_package(ZLIB)find_package(OpenCV REQUIRED )
find_package(Arrow CONFIG REQUIRED)find_package(unofficial-brotli REQUIRED)
find_package(unofficial-utf8proc CONFIG REQUIRED)
find_package(Thrift CONFIG REQUIRED)find_package(glog REQUIRED)find_package(OpenSSL REQUIRED)find_package(Boost REQUIRED COMPONENTSsystemfilesystemserializationprogram_optionsthread)find_package(DataFrame REQUIRED)if(APPLE)MESSAGE(STATUS "This is APPLE, set INCLUDE_DIRS")
set(INCLUDE_DIRS ${Boost_INCLUDE_DIRS} /usr/local/include /usr/local/iODBC/include /opt/snowflake/snowflakeodbc/include/ ${CMAKE_CURRENT_SOURCE_DIR}/../include/ ${CMAKE_CURRENT_SOURCE_DIR}/../../../include)
elseif(UNIX)MESSAGE(STATUS "This is linux, set INCLUDE_DIRS")set(INCLUDE_DIRS ${Boost_INCLUDE_DIRS} /usr/local/include ${CMAKE_CURRENT_SOURCE_DIR}/../include/   ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/)
endif(APPLE)if(APPLE)MESSAGE(STATUS "This is APPLE, set LINK_DIRS")set(LINK_DIRS /usr/local/lib /usr/local/iODBC/lib /opt/snowflake/snowflakeodbc/lib/universal)
elseif(UNIX)MESSAGE(STATUS "This is linux, set LINK_DIRS")set(LINK_DIRS ${Boost_INCLUDE_DIRS} /usr/local/lib /vcpkg/ports/cppwork/vcpkg_installed/x64-linux/lib)
endif(APPLE)if(APPLE)MESSAGE(STATUS "This is APPLE, set ODBC_LIBS")set(ODBC_LIBS iodbc iodbcinst)
elseif(UNIX)MESSAGE(STATUS "This is linux, set LINK_DIRS")set(ODBC_LIBS odbc odbcinst ltdl)
endif(APPLE)include_directories(${INCLUDE_DIRS})
LINK_DIRECTORIES(${LINK_DIRS})file( GLOB test_file_list ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) file( GLOB APP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../impl/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../include/*.h ${CMAKE_CURRENT_SOURCE_DIR}/../include/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/arr_/impl/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/http/impl/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/yaml/impl/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/df/impl/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/death_handler/impl/*.cpp)add_library(${PROJECT_NAME}_lib SHARED ${APP_SOURCES} ${test_file})
target_link_libraries(${PROJECT_NAME}_lib ${Boost_LIBRARIES} ZLIB::ZLIB glog::glog DataFrame::DataFrame ${OpenCV_LIBS})
target_link_libraries(${PROJECT_NAME}_lib OpenSSL::SSL OpenSSL::Crypto libgtest.a pystring libyaml-cpp.a libgmock.a ${ODBC_LIBS} libnanodbc.a pthread dl backtrace libzstd.a libbz2.a libsnappy.a re2::re2 parquet lz4 unofficial::brotli::brotlidec-static unofficial::brotli::brotlienc-static unofficial::brotli::brotlicommon-static utf8proc thrift::thrift  arrow arrow_dataset)foreach( test_file ${test_file_list} )file(RELATIVE_PATH filename ${CMAKE_CURRENT_SOURCE_DIR} ${test_file})string(REPLACE ".cpp" "" file ${filename})add_executable(${file}  ${test_file})target_link_libraries(${file} ${PROJECT_NAME}_lib)
endforeach( test_file ${test_file_list})

test/pimpl_idom_test.cpp

#include "death_handler/death_handler.h"
#include <glog/logging.h>
#include "person1.h"#include <utility>
#include <gtest/gtest.h>int main(int argc, char** argv) {FLAGS_log_dir = "./";FLAGS_alsologtostderr = true;// 日志级别 INFO, WARNING, ERROR, FATAL 的值分别为0、1、2、3FLAGS_minloglevel = 0;Debug::DeathHandler dh;google::InitGoogleLogging("./logs.log");testing::InitGoogleTest(&argc, argv);int ret = RUN_ALL_TESTS();return ret;
}GTEST_TEST(WrappedPimplTests, WrappedPimpl) {Person p{"Zhang San"};p.greet();
}

include/pimpl.hpp

#ifndef _FREDRIC_PIMPL_HPP_
#define _FREDRIC_PIMPL_HPP_#include <memory>template <typename T>
class PImpl {
private:std::unique_ptr<T> p_impl;
public:template <typename ... Args>PImpl(Args&& ... args): p_impl{new T(std::forward<Args>(args)...)} {}PImpl(): p_impl(new T()) {}~PImpl() {}T* operator->() {return p_impl.get();}T& operator*() {return *p_impl;}
};
#endif

include/person1.h

#ifndef _FREDRIC_PERSON1_H_
#define _FREDRIC_PERSON1_H_#include "pimpl.hpp"#include <string>class Person {
public:class PersonImpl;PImpl<PersonImpl> impl_;std::string name;Person(std::string const& name_);// 这个析构函数必须,否则可能会导致编译器找不到PersonImpl的大小// 无法工作~Person();void greet();
};
#endif

include/person1.cpp

#include "person1.h"#include <iostream>class Person::PersonImpl{
public:void greet(Person* p);
};void Person::PersonImpl::greet(Person* p) {std::cout << "Hello, my name is: " << p->name << "\n";
}Person::Person(std::string const& name_): name{name_}, impl_(){
}void Person::greet() {impl_->greet(this);
}Person::~Person() {}

程序输出如下,

C++11 使用智能指针封装 pimpl idom相关推荐

  1. C++新特性探究(18.3):C++11 weak_ptr智能指针

    C++11 weak_ptr智能指针 1.weak_ptr指针的创建 2.weak_ptr模板类提供的成员方法 例2: 程序执行结果为: 2 1 10

  2. C++新特性探究(18.2):C++11 unique_ptr智能指针详解

    C++11 unique_ptr智能指针   作为智能指针的一种,unique_ptr 指针自然也具备"在适当时机自动释放堆内存空间"的能力.和shared_ptr指针最大的不同之 ...

  3. C++新特性探究(18.1):C++11 shared_ptr智能指针

      在实际的 C++ 开发中,我们经常会遇到诸如程序运行中突然崩溃.程序运行所用内存越来越多最终不得不重启等问题,这些问题往往都是内存资源管理不当造成的.比如:   有些内存资源已经被释放,但指向它的 ...

  4. c++11中智能指针的原理,使用,实现

    文章目录 理解智能指针的原理 智能指针的使用 shared_ptr的使用 unique_ptr的使用 weak_ptr的使用 循环引用 指针指针的设计和实现: 理解智能指针的原理 c++程序设计中使用 ...

  5. c++11之智能指针

    目录 一,什么是智能指针 二,共享的智能指针shared_ptr 1. shared_ptr的初始化 3. 指定删除器 三,独占的智能指针unique_ptr 1. 初始化 2. 删除器 四, 弱引用 ...

  6. [C++11]共享智能指针shared_ptr指定删除器

    当智能指针管理的内存对应的引用计数变为 0 的时候,这块内存就会被智能指针析构掉了.另外,我们在初始化智能指针的时候也可以自己指定删除动作,这个删除操作对应的函数被称之为删除器,这个删除器函数本质是一 ...

  7. 『C++11』智能指针 匠心之作

    优缺点: 智能指针由原始指针的封装,优点是可以自动分配内存,不用担心内存泄漏问题. 用于解决独占/共享所有权指针的释放,传输等问题. 但是没有原始指针方便. 目录 一. unique_ptr 独占指针 ...

  8. C++11 unique_ptr智能指针详解

    文章目录 0.应用场景 1.初始化方式 2.常用操作 3.例子 例子1 创建unique_ptr并以引用形式传递给函数 例子2 用vector管理unique_ptr 例子3 unique_ptr作为 ...

  9. c++新特性11 (9)智能指针一”_Compressed_pair类“

    功能类似std::pair类,但是是派生关系, key 类有一个value对象 template <class _Ty1, class _Ty2, bool = is_empty_v<_T ...

最新文章

  1. 3组现代软件工程第三次作业
  2. 提高程序员工作效率的11个技巧
  3. C# 实现将网络资源保存到本地
  4. JBPM4.4整合SSH2项目
  5. swoole mysql 并发_如何用Swoole测试MySQL在特定SQL下的并发性能
  6. Python网络爬虫实训:如何下载韩寒博客文章
  7. 快速学会CAD绘制传输线路图纸
  8. 二代征信在风控流程中的使用
  9. 用Matplotlib画两张花里胡哨的图
  10. 2019年暑假第八周总结
  11. css 从右到左的方向调整
  12. Dynamics 365 Xrm.Naviagtion.navigateTo 打开Dialog后如何关闭
  13. 关闭windows server服务器的密码过期提示
  14. 三国杀小游戏(C++)
  15. vue 后台翻译_vue国际化 自动百度翻译,优先本地语言库
  16. c语言实参和形参占用存储单元_C语言程序中,当调用函数时实参和形参各占一个独立的存储单元。...
  17. 软文营销方案怎么做,软文营销策划的六大策略
  18. 帝国理工学院的计算机专业怎样,帝国理工学院计算机(人工智能与机器学习)专业怎么样?...
  19. pymol怎么做底物口袋表面_用pymol生成盒子
  20. 【小程序开发】定位功能实现

热门文章

  1. 怎么看linux Java版本,查看linux的java版本信息
  2. MT4 获取当前订单的开单价格
  3. 微信公众号怎么引流推广?分享6个实操方法给你!
  4. 163vip邮箱登录,163邮箱怎么登陆?如何登录163vip邮箱?
  5. Win10系统CLSID大全介绍
  6. c++---constructor(ctor,构造函数)
  7. Zookeeper--客户端操作
  8. 直击|知乎App增加视频回答入口 视频流归到问题下
  9. web网页设计实例作业 ——电影泰坦尼克号(4页) HTML+CSS+JavaScript 学生HTML个人网页作业作品下载 个人网页设计制作 大学生个人网站作业模板 简单个人网页制作
  10. Honor笔记本 (2018款intel版本)win11升级教程(TPM2.0)