SlideShare ist ein Scribd-Unternehmen logo
1 von 17
Downloaden Sie, um offline zu lesen
Pointer to
Implementation
idiom
What, why, how and why not something else
What is pImpl?
● A design pattern that allows you to hide
implementation details from a class
interface, during compilation
● Also known as a compiler firewall
How does pImpl look?
Why pImpl?
1. Optimize compilation time
Changes in the implementation do not require components that depend on the interface to
be recompiled
2. Hide implementation and internal dependencies completely
When distributing a precompiled library there's no "leak" of implementation details or
dependencies via private member functions that need to be in the header
3. Switch class implementations transparently to the user
Easily link with another shared library that satisfies the same interface
4. Maintain ABI compatibility
Make backward compatible changes to shared libraries without having to recompile
whatever depends on them
pImpl in practice - Code to refactor
// Gyroscope.h
#include "I2cCommunicationBus.h"
class Gyroscope
{
public:
Gyroscope(int temperature);
int getOrientation();
private:
const int mTemperature;
I2cCommunicationBus i2c;
};
// Gyroscope.cpp
Gyroscope::Gyroscope(int temperature)
: mTemperature{temperature}
{
}
int Gyroscope::getOrientation()
{
const auto registerValue = i2c.read(0xFF);
const auto adjustedOrientation = registerValue + mTemperature / 2;
return adjustedOrientation % 360;
}
pImpl implementation
// Gyroscope.h (public/shared with others)
class Gyroscope
{
public:
Gyroscope(int temperature);
~Gyroscope();
int getOrientation();
private:
class GyroscopeImpl; // Very secret
// or platform-specific
std::unique_ptr<GyroscopeImpl> mGyroscope;
};
// I2cGyroscopeImpl.cpp
#include "Gyroscope.h"
#include "I2cCommunicationBus.h"
class Gyroscope::GyroscopeImpl
{
public:
GyroscopeImpl (int temperature )
: mTemperature {temperature } {}
int getOrientation () {
// Same as before
}
private:
const int mTemperature ;
I2cCommunicationBus i2c;
};
pImpl implementation (continued)
// also in I2cGyroscopeImpl.cpp
Gyroscope::Gyroscope(int temperature )
:
mGyroscope {std::make_unique <GyroscopeImpl >(temperature )}
{}
Gyroscope::~Gyroscope () {
// Defined this in the .cpp file(s)
// or you will get incomplete type errors
}
int Gyroscope::getOrientation ()
{
return mGyroscope ->getOrientation ();
}
// Gyroscope.h (public/shared with others)
class Gyroscope
{
public:
Gyroscope(int temperature);
~Gyroscope();
int getOrientation();
private:
class GyroscopeImpl; // Very secret
// or platform-specific
std::unique_ptr<GyroscopeImpl> mGyroscope;
};
Sample build configuration (CMake)
# Public interface (Gyroscope.h)
add_library(gyroscope_interface INTERFACE)
target_include_directories(gyroscope_interface
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
# Shared (compiled) library
add_library(i2c_gyroscope_implementation SHARED
src/I2cGyroscopeImpl.cpp
src/I2cCommunicationBus.cpp)
target_include_directories(i2c_gyroscope_implementation
PRIVATE include)
target_link_libraries(i2c_gyroscope_implementation
PUBLIC
gyroscope_interface)
Using pImpl (e.g. customer's integration)
#include "Gyroscope.h"
int main()
{
Gyroscope g{42};
std::cout << g.getOrientation() << std::endl;
return 0;
}
# Variant when using I2C implementation
add_executable(i2c_gyroscope_main gyroscope_main.cpp)
target_link_libraries(i2c_gyroscope_main
PRIVATE
i2c_gyroscope_implementation)
# Variant when using SPI implementation
add_executable(spi_gyroscope_main gyroscope_main.cpp)
target_link_libraries(spi_gyroscope_main
PRIVATE
spi_gyroscope_implementation)
Why bother?
Why not an abstract factory?
ABI vs API compatibility
ABI compatibility
● Runs correctly
● Symbols in binary
● Can run with different shared libraries
(binary)
API compatibility
● Compiles successfully
● Declarations in source code
● Can compile with different revisions of
source code (text)
Abstract factory example
// BrittleGyroscope.h (public)
class BrittleGyroscope
{
public:
virtual ~BrittleGyroscope() = default;
virtual int getOrientation() = 0;
};
// GyroscopeFactory.h (public)
class GyroscopeFactory
{
public:
std::unique_ptr<BrittleGyroscope> get();
};
Abstract factory example
// I2cBrittleGyroscope.h (private)
class I2cBrittleGyroscope : public BrittleGyroscope
{
public:
int getOrientation() override;
private:
// Some dependencies we don't want to share
};
// I2cBrittleGyroscope.cpp (private/compiled)
int I2cBrittleGyroscope ::getOrientation ()
{
// Some implementation
return 123;
}
// GyroscopeFactory.cpp (private/compiled)
#include "GyroscopeFactory.h"
#include "I2cBrittleGyroscope.h"
std::unique_ptr <BrittleGyroscope > GyroscopeFactory ::get()
{
return std::make_unique <I2cBrittleGyroscope >();
}
It's all fun and games
until...
You want to make backward compatible changes
to your distributed library without having to
recompile the binary that depends on it.
Time for some live
hacking
ABI compatibility across compilers?
If you want your to distribute a shared
library that works with binaries compiled
with any compiler, then ultimately you
have to fall back to a C-compatible API, no
Standard Library types exposed in the
interface.
Thank you
Source code: https://github.com/platisd/cpp-pimpl-tutorial
Video: https://www.youtube.com/watch?v=lETcZQuKQBs

Weitere ähnliche Inhalte

Was ist angesagt?

Binary Packaging for HPC with Spack
Binary Packaging for HPC with SpackBinary Packaging for HPC with Spack
Binary Packaging for HPC with Spack
inside-BigData.com
 
yocto_scale_handout-with-notes
yocto_scale_handout-with-notesyocto_scale_handout-with-notes
yocto_scale_handout-with-notes
Steve Arnold
 

Was ist angesagt? (20)

Run Qt on Linux embedded systems using Yocto
Run Qt on Linux embedded systems using YoctoRun Qt on Linux embedded systems using Yocto
Run Qt on Linux embedded systems using Yocto
 
Podman rootless containers
Podman rootless containersPodman rootless containers
Podman rootless containers
 
App container rkt
App container rktApp container rkt
App container rkt
 
Linux day 2016 Yocto Project
Linux day 2016 Yocto ProjectLinux day 2016 Yocto Project
Linux day 2016 Yocto Project
 
C++ for the Web
C++ for the WebC++ for the Web
C++ for the Web
 
Yocto Project Dev Day Prague 2017 - Advanced class - Kernel modules with eSDK
Yocto Project Dev Day Prague 2017 - Advanced class - Kernel modules with eSDKYocto Project Dev Day Prague 2017 - Advanced class - Kernel modules with eSDK
Yocto Project Dev Day Prague 2017 - Advanced class - Kernel modules with eSDK
 
Introduction to Project atomic (CentOS Dojo Bangalore)
Introduction to Project atomic (CentOS Dojo Bangalore)Introduction to Project atomic (CentOS Dojo Bangalore)
Introduction to Project atomic (CentOS Dojo Bangalore)
 
Marco Cavallini @ LinuxLab 2018 : Workshop Yocto Project, an automatic genera...
Marco Cavallini @ LinuxLab 2018 : Workshop Yocto Project, an automatic genera...Marco Cavallini @ LinuxLab 2018 : Workshop Yocto Project, an automatic genera...
Marco Cavallini @ LinuxLab 2018 : Workshop Yocto Project, an automatic genera...
 
Yocto Project introduction
Yocto Project introductionYocto Project introduction
Yocto Project introduction
 
Yocto and IoT - a retrospective
Yocto and IoT - a retrospectiveYocto and IoT - a retrospective
Yocto and IoT - a retrospective
 
Yocto - Embedded Linux Distribution Maker
Yocto - Embedded Linux Distribution MakerYocto - Embedded Linux Distribution Maker
Yocto - Embedded Linux Distribution Maker
 
U Boot or Universal Bootloader
U Boot or Universal BootloaderU Boot or Universal Bootloader
U Boot or Universal Bootloader
 
Binary Packaging for HPC with Spack
Binary Packaging for HPC with SpackBinary Packaging for HPC with Spack
Binary Packaging for HPC with Spack
 
yocto_scale_handout-with-notes
yocto_scale_handout-with-notesyocto_scale_handout-with-notes
yocto_scale_handout-with-notes
 
Cmake kitware
Cmake kitwareCmake kitware
Cmake kitware
 
Tech Talk - Vagrant
Tech Talk - VagrantTech Talk - Vagrant
Tech Talk - Vagrant
 
Docker 활용법: dumpdocker
Docker 활용법: dumpdockerDocker 활용법: dumpdocker
Docker 활용법: dumpdocker
 
Labri 2021-invited-talk
Labri 2021-invited-talkLabri 2021-invited-talk
Labri 2021-invited-talk
 
E D - Environmental Dependencies in Python
E D - Environmental Dependencies in PythonE D - Environmental Dependencies in Python
E D - Environmental Dependencies in Python
 
Openshift meetup Paris - 21/03/2018
Openshift meetup Paris - 21/03/2018Openshift meetup Paris - 21/03/2018
Openshift meetup Paris - 21/03/2018
 

Ähnlich wie Pointer to implementation idiom

Parsley & Flex
Parsley & FlexParsley & Flex
Parsley & Flex
prideconan
 
Best Practices in apps development with Titanium Appcelerator
Best Practices in apps development with Titanium Appcelerator Best Practices in apps development with Titanium Appcelerator
Best Practices in apps development with Titanium Appcelerator
Alessio Ricco
 
BEST PRACTICES PER LA SCRITTURA DI APPLICAZIONI TITANIUM APPCELERATOR - Aless...
BEST PRACTICES PER LA SCRITTURA DI APPLICAZIONI TITANIUM APPCELERATOR - Aless...BEST PRACTICES PER LA SCRITTURA DI APPLICAZIONI TITANIUM APPCELERATOR - Aless...
BEST PRACTICES PER LA SCRITTURA DI APPLICAZIONI TITANIUM APPCELERATOR - Aless...
Whymca
 
Automated User Tests with Apache Flex
Automated User Tests with Apache FlexAutomated User Tests with Apache Flex
Automated User Tests with Apache Flex
Gert Poppe
 

Ähnlich wie Pointer to implementation idiom (20)

MicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexus
MicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexusMicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexus
MicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexus
 
Parsley & Flex
Parsley & FlexParsley & Flex
Parsley & Flex
 
Best Practices in apps development with Titanium Appcelerator
Best Practices in apps development with Titanium Appcelerator Best Practices in apps development with Titanium Appcelerator
Best Practices in apps development with Titanium Appcelerator
 
BEST PRACTICES PER LA SCRITTURA DI APPLICAZIONI TITANIUM APPCELERATOR - Aless...
BEST PRACTICES PER LA SCRITTURA DI APPLICAZIONI TITANIUM APPCELERATOR - Aless...BEST PRACTICES PER LA SCRITTURA DI APPLICAZIONI TITANIUM APPCELERATOR - Aless...
BEST PRACTICES PER LA SCRITTURA DI APPLICAZIONI TITANIUM APPCELERATOR - Aless...
 
Cloud nativemicroservices jax-london2020
Cloud nativemicroservices   jax-london2020Cloud nativemicroservices   jax-london2020
Cloud nativemicroservices jax-london2020
 
Cloud nativemicroservices jax-london2020
Cloud nativemicroservices   jax-london2020Cloud nativemicroservices   jax-london2020
Cloud nativemicroservices jax-london2020
 
Arquitecturas de microservicios - Medianet Software
Arquitecturas de microservicios   -  Medianet SoftwareArquitecturas de microservicios   -  Medianet Software
Arquitecturas de microservicios - Medianet Software
 
It's always your fault. Poznań ADG 2016
It's always your fault. Poznań ADG 2016It's always your fault. Poznań ADG 2016
It's always your fault. Poznań ADG 2016
 
Automated User Tests with Apache Flex
Automated User Tests with Apache FlexAutomated User Tests with Apache Flex
Automated User Tests with Apache Flex
 
C# Unit 2 notes
C# Unit 2 notesC# Unit 2 notes
C# Unit 2 notes
 
Java programming concept
Java programming conceptJava programming concept
Java programming concept
 
Dependency injection in iOS
Dependency injection in iOSDependency injection in iOS
Dependency injection in iOS
 
Automated User Tests with Apache Flex
Automated User Tests with Apache FlexAutomated User Tests with Apache Flex
Automated User Tests with Apache Flex
 
Java design patterns
Java design patternsJava design patterns
Java design patterns
 
Pyramid Framework
Pyramid FrameworkPyramid Framework
Pyramid Framework
 
Lecture 8_Libraries.pptx
Lecture 8_Libraries.pptxLecture 8_Libraries.pptx
Lecture 8_Libraries.pptx
 
Review: Apitrace and Vogl
Review: Apitrace and VoglReview: Apitrace and Vogl
Review: Apitrace and Vogl
 
Improving the Accumulo User Experience
 Improving the Accumulo User Experience Improving the Accumulo User Experience
Improving the Accumulo User Experience
 
Dive into Play Framework
Dive into Play FrameworkDive into Play Framework
Dive into Play Framework
 
Autotools
AutotoolsAutotools
Autotools
 

Mehr von Dimitrios Platis

Introduction to CMake
Introduction to CMakeIntroduction to CMake
Introduction to CMake
Dimitrios Platis
 

Mehr von Dimitrios Platis (10)

[GRCPP] Introduction to concepts (C++20)
[GRCPP] Introduction to concepts (C++20)[GRCPP] Introduction to concepts (C++20)
[GRCPP] Introduction to concepts (C++20)
 
OpenAI API crash course
OpenAI API crash courseOpenAI API crash course
OpenAI API crash course
 
Builder pattern in C++.pdf
Builder pattern in C++.pdfBuilder pattern in C++.pdf
Builder pattern in C++.pdf
 
Interprocess communication with C++.pdf
Interprocess communication with C++.pdfInterprocess communication with C++.pdf
Interprocess communication with C++.pdf
 
Lambda expressions in C++
Lambda expressions in C++Lambda expressions in C++
Lambda expressions in C++
 
Writing SOLID C++ [gbgcpp meetup @ Zenseact]
Writing SOLID C++ [gbgcpp meetup @ Zenseact]Writing SOLID C++ [gbgcpp meetup @ Zenseact]
Writing SOLID C++ [gbgcpp meetup @ Zenseact]
 
Introduction to CMake
Introduction to CMakeIntroduction to CMake
Introduction to CMake
 
Afry software safety ISO26262 (Embedded @ Gothenburg Meetup)
Afry software safety ISO26262 (Embedded @ Gothenburg Meetup)Afry software safety ISO26262 (Embedded @ Gothenburg Meetup)
Afry software safety ISO26262 (Embedded @ Gothenburg Meetup)
 
[grcpp] Refactoring for testability c++
[grcpp] Refactoring for testability c++[grcpp] Refactoring for testability c++
[grcpp] Refactoring for testability c++
 
Refactoring for testability c++
Refactoring for testability c++Refactoring for testability c++
Refactoring for testability c++
 

Kürzlich hochgeladen

%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
masabamasaba
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
masabamasaba
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
masabamasaba
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
masabamasaba
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
VictoriaMetrics
 

Kürzlich hochgeladen (20)

%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
Harnessing ChatGPT - Elevating Productivity in Today's Agile Environment
Harnessing ChatGPT  - Elevating Productivity in Today's Agile EnvironmentHarnessing ChatGPT  - Elevating Productivity in Today's Agile Environment
Harnessing ChatGPT - Elevating Productivity in Today's Agile Environment
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 

Pointer to implementation idiom

  • 1. Pointer to Implementation idiom What, why, how and why not something else
  • 2. What is pImpl? ● A design pattern that allows you to hide implementation details from a class interface, during compilation ● Also known as a compiler firewall
  • 4. Why pImpl? 1. Optimize compilation time Changes in the implementation do not require components that depend on the interface to be recompiled 2. Hide implementation and internal dependencies completely When distributing a precompiled library there's no "leak" of implementation details or dependencies via private member functions that need to be in the header 3. Switch class implementations transparently to the user Easily link with another shared library that satisfies the same interface 4. Maintain ABI compatibility Make backward compatible changes to shared libraries without having to recompile whatever depends on them
  • 5. pImpl in practice - Code to refactor // Gyroscope.h #include "I2cCommunicationBus.h" class Gyroscope { public: Gyroscope(int temperature); int getOrientation(); private: const int mTemperature; I2cCommunicationBus i2c; }; // Gyroscope.cpp Gyroscope::Gyroscope(int temperature) : mTemperature{temperature} { } int Gyroscope::getOrientation() { const auto registerValue = i2c.read(0xFF); const auto adjustedOrientation = registerValue + mTemperature / 2; return adjustedOrientation % 360; }
  • 6. pImpl implementation // Gyroscope.h (public/shared with others) class Gyroscope { public: Gyroscope(int temperature); ~Gyroscope(); int getOrientation(); private: class GyroscopeImpl; // Very secret // or platform-specific std::unique_ptr<GyroscopeImpl> mGyroscope; }; // I2cGyroscopeImpl.cpp #include "Gyroscope.h" #include "I2cCommunicationBus.h" class Gyroscope::GyroscopeImpl { public: GyroscopeImpl (int temperature ) : mTemperature {temperature } {} int getOrientation () { // Same as before } private: const int mTemperature ; I2cCommunicationBus i2c; };
  • 7. pImpl implementation (continued) // also in I2cGyroscopeImpl.cpp Gyroscope::Gyroscope(int temperature ) : mGyroscope {std::make_unique <GyroscopeImpl >(temperature )} {} Gyroscope::~Gyroscope () { // Defined this in the .cpp file(s) // or you will get incomplete type errors } int Gyroscope::getOrientation () { return mGyroscope ->getOrientation (); } // Gyroscope.h (public/shared with others) class Gyroscope { public: Gyroscope(int temperature); ~Gyroscope(); int getOrientation(); private: class GyroscopeImpl; // Very secret // or platform-specific std::unique_ptr<GyroscopeImpl> mGyroscope; };
  • 8. Sample build configuration (CMake) # Public interface (Gyroscope.h) add_library(gyroscope_interface INTERFACE) target_include_directories(gyroscope_interface INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) # Shared (compiled) library add_library(i2c_gyroscope_implementation SHARED src/I2cGyroscopeImpl.cpp src/I2cCommunicationBus.cpp) target_include_directories(i2c_gyroscope_implementation PRIVATE include) target_link_libraries(i2c_gyroscope_implementation PUBLIC gyroscope_interface)
  • 9. Using pImpl (e.g. customer's integration) #include "Gyroscope.h" int main() { Gyroscope g{42}; std::cout << g.getOrientation() << std::endl; return 0; } # Variant when using I2C implementation add_executable(i2c_gyroscope_main gyroscope_main.cpp) target_link_libraries(i2c_gyroscope_main PRIVATE i2c_gyroscope_implementation) # Variant when using SPI implementation add_executable(spi_gyroscope_main gyroscope_main.cpp) target_link_libraries(spi_gyroscope_main PRIVATE spi_gyroscope_implementation)
  • 10. Why bother? Why not an abstract factory?
  • 11. ABI vs API compatibility ABI compatibility ● Runs correctly ● Symbols in binary ● Can run with different shared libraries (binary) API compatibility ● Compiles successfully ● Declarations in source code ● Can compile with different revisions of source code (text)
  • 12. Abstract factory example // BrittleGyroscope.h (public) class BrittleGyroscope { public: virtual ~BrittleGyroscope() = default; virtual int getOrientation() = 0; }; // GyroscopeFactory.h (public) class GyroscopeFactory { public: std::unique_ptr<BrittleGyroscope> get(); };
  • 13. Abstract factory example // I2cBrittleGyroscope.h (private) class I2cBrittleGyroscope : public BrittleGyroscope { public: int getOrientation() override; private: // Some dependencies we don't want to share }; // I2cBrittleGyroscope.cpp (private/compiled) int I2cBrittleGyroscope ::getOrientation () { // Some implementation return 123; } // GyroscopeFactory.cpp (private/compiled) #include "GyroscopeFactory.h" #include "I2cBrittleGyroscope.h" std::unique_ptr <BrittleGyroscope > GyroscopeFactory ::get() { return std::make_unique <I2cBrittleGyroscope >(); }
  • 14. It's all fun and games until... You want to make backward compatible changes to your distributed library without having to recompile the binary that depends on it.
  • 15. Time for some live hacking
  • 16. ABI compatibility across compilers? If you want your to distribute a shared library that works with binaries compiled with any compiler, then ultimately you have to fall back to a C-compatible API, no Standard Library types exposed in the interface.
  • 17. Thank you Source code: https://github.com/platisd/cpp-pimpl-tutorial Video: https://www.youtube.com/watch?v=lETcZQuKQBs