Better Code: Runtime Polymorphism - Sean Parent

Поділитися
Вставка
  • Опубліковано 4 жов 2024
  • This talk explains why (and how) to implement polymorphism without inheritance in C++.
    The talk contains many C++ tips and techniques, including many new features from C++11. During the course of that talk a key feature from Photoshop will be demonstrated and implemented.
    NDC Conferences
    ndc-london.com
    ndcconferences...

КОМЕНТАРІ • 75

  • @gulagz1549
    @gulagz1549 5 років тому +22

    "My class inherits from nothing." This is my favorite dev video of all time.

    • @kristupasantanavicius9093
      @kristupasantanavicius9093 5 років тому +5

      A java programming would create a base class "Object" and would make sure that all of his other classes inherit from it 😂

    • @theevilcottonball
      @theevilcottonball 4 місяці тому

      As a C programmer this is nothing special.

    • @HowDoYouUseSpaceBar
      @HowDoYouUseSpaceBar 2 місяці тому

      @@theevilcottonball As a programmer this is nothing special.

    • @theevilcottonball
      @theevilcottonball 2 місяці тому

      @@HowDoYouUseSpaceBar
      Yes, because people who don't know C are not programmers...

  • @minimatamou8369
    @minimatamou8369 7 років тому +18

    42:20 JUST DO IT ! Don't let your dreams be dreams !
    Love this talk, Sean Parent is awesome as always.

  • @nidefawl2552
    @nidefawl2552 2 роки тому +6

    I have been using this pattern for the past 5 years now. It uses so little boilerplate for what it achieves. I learned to apply similar techniques all over my code.

  • @ChristianBrugger
    @ChristianBrugger 2 роки тому +1

    Amazing how similar the talk is to the one in 2011 and still it's more relevant that ever!

  • @echosystemd
    @echosystemd 7 років тому +4

    I could watch this talk every day.

    • @gulagzulka2188
      @gulagzulka2188 6 років тому

      I know... I feel the same way. He presents complex topics in a way that doesn't freak you out. And it's not that he talks down to his audience. Not at all. He's just calm and assured and it rubs off.

    • @llothar68
      @llothar68 5 років тому

      @@gulagzulka2188 Well i did freak out the first time, but in a way of "i want to understand this C++ kung fu" not in a "go away you ugly orc" freak out.

    • @kormisha
      @kormisha 4 роки тому

      This is probably the first talk which is not clear. May be on second go, it will become more clear. You loose the thread after a while and not really clear what is real benefit. Despite all this evil things about inheritance, it is a better option in 99% of cases than the final implementation in this talk.

  • @johnappleseed8839
    @johnappleseed8839 6 років тому +28

    You must execute epic feats of complex and subtle language kung fu to beat C++ into semantic submission.

  • @tedchirvasiu
    @tedchirvasiu 3 роки тому +3

    His voice is very calming

  • @spacechild2
    @spacechild2 8 місяців тому +2

    Great talk! The only thing I'd disagree with is that mutable polymorphic objects are an extreme exception. In my experience, they are rather common. For example, imagine an abstract base class for an audio plugin with a process() method. Each concrete plugin would override the process() method to implement their DSP algorithm. This method must be non-const because some plugins need to maintain and mutate state, e.g. a filter or delay line. The host application, however, doesn't care about the implementation details, it just wants to process audio buffers by passing them to the process() method of each plugin in a particular order.

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

    Great talk and a great pattern. Small code improvement: instead of assert(x.size()) use assert(!x.empty()) - it is more clear about the intent and does not require the container to know or compute its size (linked lists size() can be O(n) but empty() is O(1)).

    • @ChristianBrugger
      @ChristianBrugger 2 роки тому +1

      Just a small addition, since c++11 the size operation of any standard container needs to be O(1), including list.

  • @kruel9669
    @kruel9669 7 років тому +23

    Thanks for the great talk!
    Just wanted to add that the description is a bit misleading: there is inheritance involved. It is just hidden from the library user and done automatically "on use" through a template.

    • @kwanarchive
      @kwanarchive 7 років тому +11

      Yes. It should be "without requiring inheritance from the library user".

  • @mathiaskohler383
    @mathiaskohler383 4 роки тому

    Excellent! I will watch this again. Thanks.

  • @steveneckhoff8632
    @steveneckhoff8632 5 років тому +1

    This guy codes! Great talk!

  • @Yupppi
    @Yupppi 10 місяців тому +1

    At some point this started to remind of the old meme "yo dawg I heard you liked documents so I put your document inside your document"

  • @gulagzulka2188
    @gulagzulka2188 6 років тому +6

    @29:44 -- I'm running the same code with C++17 gcc 5.4.0 and I don't get the copy constructor call. I only get the two ctor calls. So that issue with the compiler deleting the default copy/move assignment for classes with non-static data members or direct base classes NOT defining a move assignment operator appears to be mitigated.

  • @Saschaborg
    @Saschaborg 5 років тому

    WOW!! I'd say this is a *very big* part of a concept to solve "modern problems with OOP" regarding multithreading performance - since polymorphism (as one of THE most valuable features of OOP!) comes with all different kinds of drawbacks, usually. :-) Thanks for this inspirational presentation!

  • @hardenedapple
    @hardenedapple 7 років тому +2

    Reminds me of common lisp's generic functions -- (defmethod draw (obj) ... ) -- nice talk!

    • @llothar68
      @llothar68 5 років тому

      It's exactly this. Both break down polymorphism (the virtual method function table in C++ implementations) from class to function level. But Lisp is hidding all this and with its non static typed nature has a lot of ways to make it easy.

  • @dekadebashish
    @dekadebashish 4 роки тому +1

    Great Talk!

  • @tux1968
    @tux1968 2 роки тому +4

    @49:22 This is not a demonstration that the copy constructor isn't still being called many times. Since you deleted the explicit copy constructor instrumented to print "Copy", you didn't need to make any of the other changes to have the same output. There is no way to see if the implicitly compiler-generated copy constructor is still being called. Not sure how to make an actual, proper demonstration of success; when I add an instrumented copy back in, it is indeed still disappointingly being called many times.

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

      I rewatched several time this.
      Shame that no one else noticed that.
      "Whach my hands I remove the print {copy} and remove the copy/move ctors and you see there is no copy" )))) lol that's epic fail.
      What about default ones. Try to expicitly delete the ctors and code won't compile.

  • @User-cv4ee
    @User-cv4ee Рік тому +2

    Didn't we lose the equality semantics of a regular type for the `int` wrapper class at 21:00? If I copy an object and check for equality it would return false cause the `unique_ptr`s would point to different objects.

  • @monsterpda
    @monsterpda 6 років тому +1

    I wanna like this more than once

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

    He is a wizard

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

    I think I'm missing something obvious at 46:57, there is 2 objects in the document when he commit(), but there's 4 copies. Why is there 4 copies not 2?

  • @WarHero56
    @WarHero56 2 роки тому +1

    at around 7:20, if emplace_back fails to allocate memory, doesn't that mean we're out of RAM and we have bigger problems than leaking memory because the program is about to crash anyways.

  • @apivovarov2
    @apivovarov2 9 місяців тому

    @25:52 It looks like a copy-and-swap idiom. Why we use move (and move assignment) here instead of using swap for selfs?

  • @lapinrigolo
    @lapinrigolo 7 років тому +6

    Any textual description of the talk?

    • @vasiliigulevich9202
      @vasiliigulevich9202 8 місяців тому

      Sure! Promote value semantics. Hide polymorphism. To do so, make polymorphic wrappers of values at the point of type erasure. The guy literally spend an hour saying two sentences.

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

    Here are the slides: sean-parent.stlab.cc/presentations/2017-01-18-runtime-polymorphism/2017-01-18-runtime-polymorphism.pdf

  • @robbie_
    @robbie_ 6 років тому +4

    Trying to understand this. How is it different from the pimpl idiom? ...

    • @gulagzulka2188
      @gulagzulka2188 6 років тому +2

      Basically it isn't. He's using containment instead of inheritance to achieve polymorphism, and Pimpl is based on containment too. This just takes it a little further.

    • @puyadaravi3109
      @puyadaravi3109 4 роки тому

      21:45

  • @H2CO3Szifon
    @H2CO3Szifon 6 років тому +2

    52:18 - neither Go or Swift goes anywhere near or as far as Rust when it comes to polymorphic value types.

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

    What happens to Photoshop's undo history if I use a filter globally on a huge document? Sparse tiling won't help.

  • @JiveDadson
    @JiveDadson 6 років тому +3

    Is there any place on the web where I can find the final code? There is no slide in this vid that shows the whole thing on one screen.

    • @767Steel
      @767Steel 6 років тому +6

      There's link at the of the presentation.
      sean-parent.stlab.cc/papers-and-presentations/#better-code-runtime-polymorphism

  • @CR3271
    @CR3271 2 роки тому

    38:08 he says there are potential performance gains because you don't have to wrap strings or ints in a class. Yet that's exactly what he's doing under the hood. Seems to me if I wrote a wrapper class for int or string with all his little copy/move optimizations, it would be the same code for all intents and purposes. Maybe more convenient for a library consumer to code against, but no different performance-wise. What am I missing? I'd love to see some benchmarks on the two coding styles.

    • @dzarek1039
      @dzarek1039 2 роки тому +2

      Yes and no. There is a wrapper, but it is in a class that actually needs polymorphism. So, you only have the overhead where it is actually needed, in a polymorphic scenario.You can still use int and std::string directly (without wrapper) and still use non-virtual draw() on them in non-polymorphic scenarios.

  • @gongfei
    @gongfei 7 років тому +8

    5 people audience?

    • @WalderFrey
      @WalderFrey 6 років тому +5

      Apparently, for one the most interesting talkers you could 'give up' an hour listening to.

    • @llothar68
      @llothar68 5 років тому +2

      25000 viewers. Nobody who get recorded at that events (with lots of overlapping sessions - i guess) is talking to the physical audience.

    • @pmcgee003
      @pmcgee003 2 роки тому

      @@llothar68 now 55k 🙂

  • @kormisha
    @kormisha 4 роки тому +1

    Explanation of incidental data structure did not make any sense to me.

  • @perfectionbox
    @perfectionbox 4 роки тому

    If you resize a photoshop document, does that reset the history? Wouldn't the sparse tile system get confused?

  • @GeatMasta
    @GeatMasta 4 роки тому +1

    Why not delete the copy constructor and define the move constructor? Isn’t it kind of dishonest to say that this is a copy when its a move.

  • @sabetaytoros4123
    @sabetaytoros4123 6 років тому +1

    Can someone explain me why do we need the abstract virtual base struct concept_t ?
    Concept struct is used by the Type Copy Assignment function.
    Since the compiler would write the copy assignment function for every type that we use do we need another indirection.

    • @oliviercorrio4566
      @oliviercorrio4566 6 років тому +5

      I think it is because all type in the vector must be of the same type. A vector of shared_ptr is not the same as shared_ptr even if it is a pointer inside. So with that all elements in vector are of type concept_t.

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

      @@oliviercorrio4566 You also need it to be virtual for having polymorphic behavior of draw and the destructor.

  • @ashrasmun1
    @ashrasmun1 5 років тому

    I'm sorry, but I'm not seeing it. You say at 38:00 that you don't need to wrap your ints or strings into objects, but don't you wrap them anyway (model)? You just hide it from the client.

    • @JanuarAndaria
      @JanuarAndaria 5 років тому +1

      he talking about the Deep Problem #3, 13:59.

  • @sunipmukherjee2130
    @sunipmukherjee2130 3 місяці тому +1

    Basically Rust traits but more boilerplate. Gotchu.

  • @ruixue6955
    @ruixue6955 6 років тому +3

    2:36 what is inheritance

    • @usx95
      @usx95 6 років тому

      lol

  • @noxmetus
    @noxmetus 6 років тому

    At 38:06. It's not true. You do have to wrap integers and strings into objects. This is what object_t is. Btw, it's the same technique std::shared_ptr uses to store custom deleters. The basic idea of the rest of the code is how to use function overloading for polymorphism.

  • @TechnologyRules
    @TechnologyRules 4 роки тому +4

    Yeah, Photoshop is just so slow that I can't even see how can someone use it as an example of optimized software.

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

      write a better alternative with even half the functionality ? ;D

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

      @@none_of_your_business Not sure if you actually read it, but the point is not functionality in what I said. I was talking about *performance*. Why are you licking his b4lls? Shut your mouth.

  • @남세2
    @남세2 2 роки тому

    6:11 "how many people see the bug?" ... Me: WHAT!? BUG?!?!?!?!!?!?

  • @juaxix
    @juaxix 6 років тому +1

    This class document looks like xml ...but it would be better if it was protobuf :D

  • @llothar68
    @llothar68 5 років тому +1

    C++ could be so much easier if the language would implement free function overload and polymorphism on more then just the first argument (the implicit this argument) like CLOS (the lisp object system). This is exactly what this concept classes do by foot. But hey maybe we get this in C++44. Glaciers move faster then this language comittee.

    • @greenfloatingtoad
      @greenfloatingtoad 5 років тому +2

      Andrei Alexandrescu goes over different techniques to implement this with templates in chapter 11 of Modern C++ Design, if you're willing to put up with template magic to use multimethods before 2044!

  • @Fleshbits1
    @Fleshbits1 7 місяців тому

    Quantify "indirection, heap allocation, and virtualization impact my performance"... by how much? 1 nanosecond? Is it more than adding two integers together? Do we analyze the performance of addition and subtraction? I don't understand why everyone is so dogmatic about these things unless they actually have constraints where they are doing something that has to run in 100ns or on 16k of memory. .. and sure those situations exist, but I am getting really tired of talking about a few nanoseconds of performance while we are waiting a full second for a user to click a button. How many cpu cycles does it really take to allocate an object? and don't you only allocate it once? How many cpu cycles does indirection take up? one? five?

    • @skyletoft
      @skyletoft 2 місяці тому

      > How many cycles does indirection eat up?
      Literally thousands if it's not in recent cache.
      And if you don't neet to care about the performance on this level you shouldn't be using something as user unfriendly as C++. If you can afford the performance, use literally anything else.