Skip to content

C.120 Understanding "Do not use inheritance when simply having a data member will do." #1963

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ghost opened this issue Aug 15, 2022 · 8 comments
Assignees

Comments

@ghost
Copy link

ghost commented Aug 15, 2022

  1. If inheritance is avoided in favor of an object as a data member (as applicable), then in order to expose functions of the data member object for simplicity, must wrapper functions be used?
  2. If No. 1 is true, that is considerable additional code that could objectively be considered superfluous - agree?
@ghost ghost closed this as completed Aug 16, 2022
@ghost ghost reopened this Aug 20, 2022
@jwakely
Copy link
Contributor

jwakely commented Aug 20, 2022

It's not superfluous if it avoids unwanted coupling and other unwanted effects like derived-to-base conversions, ADL, slicing etc.

@ghost
Copy link
Author

ghost commented Aug 20, 2022

Thank you, Jonathan, for confirming that wrapping is a reasonable approach. At the same time, I propose, that some might choose to ignore this guideline in some cases. and wait until the language has support for automatically exposing functions of object data members at the containing object interface (for example expose public SomeClass _someMember;).

@jwakely
Copy link
Contributor

jwakely commented Aug 21, 2022

The guidelines cannot cover all situations. If waiting indefinitely for a hypothetical language extension that isn't on the agenda is the right call for your project, that's your call.

The guideline seems correct as written for today's C++ language.

@ghost
Copy link
Author

ghost commented Aug 23, 2022

This also relates to whether wrapper functions to expose data object members would ever be needed because if the data member is the correct decision based on overall application design, then exposing the functions might not make sense. In that case, my syntax suggestion would also not be applicable because the usefulness of wrappers would not apply.

I think that the key with C.120 is not whether "a data member will do" 🙂. As we know, inheritance is (very 🙂) useful but not essential, so one could always design around inheritance and use data members - or vice-verse one can force inheritance by deciding to make constructor or other functions protected etc. The real decision is whether inheritance efficiently and intelligently serves the goals of the application. This relates more to the type as a concept, and the concept itself, again, relates to the goals of the application.

@BenjamenMeyer
Copy link

BenjamenMeyer commented Aug 23, 2022

@CompCodeNet When reading C.120 I read it more as if you're using a pure data object then don't use inheritance.

C.120 could probably be enhanced with a good example of that portion of the guideline; not none of the examples - good or bad - presently speak to it. That would probably help folks better understand it.

@ghost
Copy link
Author

ghost commented Aug 24, 2022

@BenjamenMeyer Thank you, an example is helpful. However, I also think that the starting point should be to explain the purpose of inheritance as a language capability. As discussed in previous post, the purpose of inheritance is to abstract or extend types that fulfill a conceptual role. So, one would only want to inherit (including multiple) if the resulting (derived) exposed interface fits the concept of the type. I.e. What you are inheriting is in line with the type's concept. From this understanding, one can then distinguish between internal members that support the implementation of the class's concept vs. exposed functions that manifest the class's concept.

@ghost ghost closed this as completed Sep 9, 2022
@ghost
Copy link
Author

ghost commented Sep 9, 2022

@jwakely I can see that inline wrappers for contained objects would essentially be "comments" since the compiler would turn them into NOPs except the actual _containedObject.SomeFunction( ) call. I can also see that it's a decent approach to keeping code clean and simple. The only other point that I was making is that it's good if the language can accommodate these things in syntax and thus reduce the verbosity.

@ghost ghost reopened this Sep 14, 2022
@hsutter
Copy link
Contributor

hsutter commented Sep 22, 2022

Editors call: @jwakely answered this well. Thanks!

@hsutter hsutter closed this as completed Sep 22, 2022
@hsutter hsutter self-assigned this Sep 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants