Effective C++ Item 23 Prefer non-member non-friend functions to member functions

后端 未结 7 1955
隐瞒了意图╮
隐瞒了意图╮ 2020-11-27 03:09

While puzzling with some facts on class design, specifically whether the functions should be members or not, I looked into Effective c++ and found Item 23, namely, Prefer no

7条回答
  •  一向
    一向 (楼主)
    2020-11-27 03:26

    Various thoughts:

    • It's nice when non-members work through the class's public API, as it reduces the amount of code that:
      • needs to be carefully monitored to ensure class invariants,
      • needs to be changed if the object's implementation is redesigned.
    • When that isn't good enough, a non-member can still be made a friend.
    • Writing a non-member function is usually a smidgeon less convenient, as members aren't implicitly in scope, BUT if you consider program evolution:
      • Once a non-member function exists and it is realised that the same functionality would be useful for other types, it's generally very easy to convert the function to a template and have it available not just for both types, but for arbitrary future types too. Put another way, non-member templates allow even more flexible algorithm reuse than run-time polymorphism / virtual dispatch: templates allow something known as duck typing.
      • An existing type sporting a useful member function encourages cut-and-paste to the other types that would like analogous behaviour because most ways of converting the function for re-use require that every implicit member access be made an explicit access on a particular object, which is going to be a more tedius 30+ seconds for the programmer....
    • Member functions allow the object.function(x, y, z) notation, which IMHO is very convenient, expressive and intuitive. They also work better with discovery/completion features in many IDE's.
    • A separation as member and non-member functions can help communicate the essential nature of the class, it's invariants and fundamental operations, and logically group the add-on and possibly ad-hoc "convenience" features. Consider Tony Hoare's wisdom:

      "There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult."

      • Here, non-member usage isn't necessarily far more difficult, but you do have to think more about how you're accessing member data and private/protected methods and why, and which operations are fundamental. Such soul searching would improve the design with member functions too, it's just easier to be lazy about :-/.
    • As non-member functionality expands in sophistication or picks up additional dependencies, the functions can be moved into separate headers and implementation files, even libraries, so users of the core functionality only "pay" for using the parts they want.

    (Omnifarious's answer is a must-read, thrice if it's new to you.)

提交回复
热议问题