The Pointer to Implementation (pImpl) idiom in C++

Поділитися
Вставка
  • Опубліковано 21 лют 2021
  • The Pointer to Implementation (pImpl) idiom in C++ is one technique that allows you to hide implementation details from an interface.
    NOTICE: Perhaps the most important benefit of pImpl was not given the appropriate focus. I consider as its most important advantage (and mentioned first in the video) to be that changes in the implementation do not require components that depend on the interface to be recompiled.
    This is very important when distributing precompiled libraries since your users' software will be binary compatible with your different deliveries regardless of the changes you do as long as the public interface is not modified. This allows you to update your libraries in a system without requiring your users to recompile their programs. In other words, your internal changes are completely transparent to the users/customers.
    You can find a written form of the tutorial and all the code on GitHub: github.com/platisd/cpp-pimpl-...
    Please like, subscribe, comment and share the video to help me produce more content like this! :)
    Want to buy me a coffee so I can keep making free videos? Then please do so here: buymeacoff.ee/platisd

КОМЕНТАРІ • 21

  • @maxprex
    @maxprex 3 роки тому +14

    That was beautifully explained. I especially love how you enunciate the key parts that often cause confusion. Thank you!

    • @platisd
      @platisd  3 роки тому +4

      Thanks! I sometimes fear that some viewers might find the slower enunciations awkward, so it's good to hear that others like them. 😅

  • @NickEnchev
    @NickEnchev 12 днів тому

    Surprisingly good video!

  • @arnoldtharrington2087
    @arnoldtharrington2087 Рік тому +2

    Very clear explanation of pimpl. I'm adding you to my subscriptions.

  • @guitarheroua
    @guitarheroua 3 роки тому +1

    Nice explanation! I really like your videos and glad that found your channel. Thanks for your work!

    • @platisd
      @platisd  3 роки тому

      Thanks a lot Andriy! :)

  • @debashishdeka7698
    @debashishdeka7698 3 роки тому

    Loud and clear

  • @anirbansengupta8465
    @anirbansengupta8465 3 роки тому

    Thanks for making wonderful contents

  • @jgmccabe
    @jgmccabe Рік тому +1

    I believe you mentioned that this is a technique appropriate to specialisation at link-time, i.e., if you wanted to use a SPI comms interface instead of I2C for an application, that would require the source code for Gyroscope::GyroscopeImpl in Gyroscope.cpp to be physically different. Is that correct? If you wanted to decide, at run-time, whether to use SPI or I2C, would you extract an interface, say CommsDevice, implemented by I2cCommsDevice and SpiCommsDevice with a pointer to the interface held in the GyroscopeImpl class, and passed in via, e.g. its constructor (or a setter function)? (Sorry to use Java terms so much, but they are clearer than C++ - 'interface' - > 'pure virtual base class' etc 😂).

    • @platisd
      @platisd  Рік тому

      I am a bit confused because `Gyroscope.cpp` doesn't include any `GyroscopeImpl` and then you lost me about the part where a pointer is being passed via a setter or constructor.
      I suspect passing anything via the constructor/setter will defeat the purpose of hiding the implementation, but I could be misunderstanding you.
      How about this: UA-cam isn't the right platform for such discussions, what if we take it on GitHub instead?
      Could you please open an issue in the repo (github.com/platisd/cpp-pimpl-tutorial) add any code snippets or links to files you think are necessary and then I promise you we will get to the bottom of this. :)

  • @juliankandlhofer7553
    @juliankandlhofer7553 3 роки тому

    Very interesting. This seems very similar to something like java Interfaces, where a consumer just knows about the interface and nothing about the implementation, right?

    • @platisd
      @platisd  3 роки тому +1

      Well, kind of. There are JAVA-like interfaces (i.e. "pure abstract classes") in C++ as well, so those would be the direct equivalent. pImpl allows compatibility on a binary level as well, i.e. an even looser coupling. So if component "A" depends on a common interface "Foo" that is implement by "BarFoo" and everything is compiled together, then if "BarFoo" changes then "A" has to be recompiled.
      On the other hand, if BarFoo was hidden behind the pImpl idiom, you wouldn't have to recompile "A" or you could even switch the library out on your filesystem completely, with something else. This is the most common use case for pImpl as far as I know. You can let your user/customer depend on your library (e.g. a .so or .dll file) and if you make changes to it, you can switch it out to another one as long as you haven't changed the public interface.

    • @juliankandlhofer7553
      @juliankandlhofer7553 3 роки тому

      @@platisd Ahh so ABI stability. Thanks for explaining!

  • @anthonymonterrosa4383
    @anthonymonterrosa4383 3 роки тому

    At the end you say you prefer not to use the pattern yourself. I think it could be enlightening to use listeners to understand why. Is it because of link-time optimization? Because it's ugly? Because boilerplate?

    • @platisd
      @platisd  3 роки тому +1

      Great question Anthony!
      I didn't elaborate further on that because I wanted to keep the video mainly about pImpl and not its alternatives.
      I would only use the idiom if I was distributing a library and I wouldn't want (or it wouldn't be feasible) software the depends on it to have to be recompiled every time I update inner implementation of the library. In other words, if I'd go for pImpl if wanted to keep the ABI of my library stable across updates.
      If that wasn't the case, I would prefer some kind of polymorphism, static or runtime. I would use polymorphism instead because I find pImpl more complicated to use & understand as well as relatively less testable.

  • @KobiCohenArazi
    @KobiCohenArazi 3 роки тому +2

    Gyro::~Gyro() = default; should also work (instead empty impl { })

    • @platisd
      @platisd  3 роки тому +1

      It would indeed! 👍

    • @KobiCohenArazi
      @KobiCohenArazi 3 роки тому

      @@platisd great video btw. keep it up! :)

  • @greatbullet7372
    @greatbullet7372 3 роки тому +1

    I2C in reality means i square c :D

  • @mashtonish
    @mashtonish 7 днів тому

    rampant acronyms, "code smells", pimpl... sometimes the things people come up with are gross.