C++11 使用智能指针封装 pimpl idom
程序结构如下,
本例主要使用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相关推荐
- C++新特性探究(18.3):C++11 weak_ptr智能指针
C++11 weak_ptr智能指针 1.weak_ptr指针的创建 2.weak_ptr模板类提供的成员方法 例2: 程序执行结果为: 2 1 10
- C++新特性探究(18.2):C++11 unique_ptr智能指针详解
C++11 unique_ptr智能指针 作为智能指针的一种,unique_ptr 指针自然也具备"在适当时机自动释放堆内存空间"的能力.和shared_ptr指针最大的不同之 ...
- C++新特性探究(18.1):C++11 shared_ptr智能指针
在实际的 C++ 开发中,我们经常会遇到诸如程序运行中突然崩溃.程序运行所用内存越来越多最终不得不重启等问题,这些问题往往都是内存资源管理不当造成的.比如: 有些内存资源已经被释放,但指向它的 ...
- c++11中智能指针的原理,使用,实现
文章目录 理解智能指针的原理 智能指针的使用 shared_ptr的使用 unique_ptr的使用 weak_ptr的使用 循环引用 指针指针的设计和实现: 理解智能指针的原理 c++程序设计中使用 ...
- c++11之智能指针
目录 一,什么是智能指针 二,共享的智能指针shared_ptr 1. shared_ptr的初始化 3. 指定删除器 三,独占的智能指针unique_ptr 1. 初始化 2. 删除器 四, 弱引用 ...
- [C++11]共享智能指针shared_ptr指定删除器
当智能指针管理的内存对应的引用计数变为 0 的时候,这块内存就会被智能指针析构掉了.另外,我们在初始化智能指针的时候也可以自己指定删除动作,这个删除操作对应的函数被称之为删除器,这个删除器函数本质是一 ...
- 『C++11』智能指针 匠心之作
优缺点: 智能指针由原始指针的封装,优点是可以自动分配内存,不用担心内存泄漏问题. 用于解决独占/共享所有权指针的释放,传输等问题. 但是没有原始指针方便. 目录 一. unique_ptr 独占指针 ...
- C++11 unique_ptr智能指针详解
文章目录 0.应用场景 1.初始化方式 2.常用操作 3.例子 例子1 创建unique_ptr并以引用形式传递给函数 例子2 用vector管理unique_ptr 例子3 unique_ptr作为 ...
- c++新特性11 (9)智能指针一”_Compressed_pair类“
功能类似std::pair类,但是是派生关系, key 类有一个value对象 template <class _Ty1, class _Ty2, bool = is_empty_v<_T ...
最新文章
- 3组现代软件工程第三次作业
- 提高程序员工作效率的11个技巧
- C# 实现将网络资源保存到本地
- JBPM4.4整合SSH2项目
- swoole mysql 并发_如何用Swoole测试MySQL在特定SQL下的并发性能
- Python网络爬虫实训:如何下载韩寒博客文章
- 快速学会CAD绘制传输线路图纸
- 二代征信在风控流程中的使用
- 用Matplotlib画两张花里胡哨的图
- 2019年暑假第八周总结
- css 从右到左的方向调整
- Dynamics 365 Xrm.Naviagtion.navigateTo 打开Dialog后如何关闭
- 关闭windows server服务器的密码过期提示
- 三国杀小游戏(C++)
- vue 后台翻译_vue国际化 自动百度翻译,优先本地语言库
- c语言实参和形参占用存储单元_C语言程序中,当调用函数时实参和形参各占一个独立的存储单元。...
- 软文营销方案怎么做,软文营销策划的六大策略
- 帝国理工学院的计算机专业怎样,帝国理工学院计算机(人工智能与机器学习)专业怎么样?...
- pymol怎么做底物口袋表面_用pymol生成盒子
- 【小程序开发】定位功能实现
热门文章
- 怎么看linux Java版本,查看linux的java版本信息
- MT4 获取当前订单的开单价格
- 微信公众号怎么引流推广?分享6个实操方法给你!
- 163vip邮箱登录,163邮箱怎么登陆?如何登录163vip邮箱?
- Win10系统CLSID大全介绍
- c++---constructor(ctor,构造函数)
- Zookeeper--客户端操作
- 直击|知乎App增加视频回答入口 视频流归到问题下
- web网页设计实例作业 ——电影泰坦尼克号(4页) HTML+CSS+JavaScript 学生HTML个人网页作业作品下载 个人网页设计制作 大学生个人网站作业模板 简单个人网页制作
- Honor笔记本 (2018款intel版本)win11升级教程(TPM2.0)