Why does C++ forbid private inheritance of a final class?










7














C++11 introduced the final keyword to C++.



It can be used on a virtual method or on a class.



Declaring a class final forbids any kind of inheritance: public, protected and private.



struct A final 
;

class B: private A
;

error: base 'A' ^ is marked 'final'


While it can be reasonable to forbid public inheritance (e.g. if my class doesn't have a virtual destructor, or for other reasons), why should I forbid private inheritance?



Might it be that if final forbade only public inheritance, that std::string and its other friends in std would have been final -- as they should -- for not having a virtual destructor?



EDIT:



Howard Hinnant already answered Why the standard containers are not final but still, there is a reason for declaring a class final but allowing private inheritance.










share|improve this question



















  • 8




    Not having a virtual destructor does not prohibit or limit inheritance anyhow. It only makes ownership over object through a pointer to base class faulty. So that is not a reason for making std::string and most of other library classes final.
    – VTT
    22 hours ago











  • How would that hypothetical feature work? Assume you can derive (if only privately) from a final class. Would virtual functions be treated as final?
    – curiousguy
    16 hours ago















7














C++11 introduced the final keyword to C++.



It can be used on a virtual method or on a class.



Declaring a class final forbids any kind of inheritance: public, protected and private.



struct A final 
;

class B: private A
;

error: base 'A' ^ is marked 'final'


While it can be reasonable to forbid public inheritance (e.g. if my class doesn't have a virtual destructor, or for other reasons), why should I forbid private inheritance?



Might it be that if final forbade only public inheritance, that std::string and its other friends in std would have been final -- as they should -- for not having a virtual destructor?



EDIT:



Howard Hinnant already answered Why the standard containers are not final but still, there is a reason for declaring a class final but allowing private inheritance.










share|improve this question



















  • 8




    Not having a virtual destructor does not prohibit or limit inheritance anyhow. It only makes ownership over object through a pointer to base class faulty. So that is not a reason for making std::string and most of other library classes final.
    – VTT
    22 hours ago











  • How would that hypothetical feature work? Assume you can derive (if only privately) from a final class. Would virtual functions be treated as final?
    – curiousguy
    16 hours ago













7












7








7







C++11 introduced the final keyword to C++.



It can be used on a virtual method or on a class.



Declaring a class final forbids any kind of inheritance: public, protected and private.



struct A final 
;

class B: private A
;

error: base 'A' ^ is marked 'final'


While it can be reasonable to forbid public inheritance (e.g. if my class doesn't have a virtual destructor, or for other reasons), why should I forbid private inheritance?



Might it be that if final forbade only public inheritance, that std::string and its other friends in std would have been final -- as they should -- for not having a virtual destructor?



EDIT:



Howard Hinnant already answered Why the standard containers are not final but still, there is a reason for declaring a class final but allowing private inheritance.










share|improve this question















C++11 introduced the final keyword to C++.



It can be used on a virtual method or on a class.



Declaring a class final forbids any kind of inheritance: public, protected and private.



struct A final 
;

class B: private A
;

error: base 'A' ^ is marked 'final'


While it can be reasonable to forbid public inheritance (e.g. if my class doesn't have a virtual destructor, or for other reasons), why should I forbid private inheritance?



Might it be that if final forbade only public inheritance, that std::string and its other friends in std would have been final -- as they should -- for not having a virtual destructor?



EDIT:



Howard Hinnant already answered Why the standard containers are not final but still, there is a reason for declaring a class final but allowing private inheritance.







c++ final






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 18 hours ago









Boann

36.7k1287121




36.7k1287121










asked 22 hours ago









Amir Kirsh

1,338819




1,338819







  • 8




    Not having a virtual destructor does not prohibit or limit inheritance anyhow. It only makes ownership over object through a pointer to base class faulty. So that is not a reason for making std::string and most of other library classes final.
    – VTT
    22 hours ago











  • How would that hypothetical feature work? Assume you can derive (if only privately) from a final class. Would virtual functions be treated as final?
    – curiousguy
    16 hours ago












  • 8




    Not having a virtual destructor does not prohibit or limit inheritance anyhow. It only makes ownership over object through a pointer to base class faulty. So that is not a reason for making std::string and most of other library classes final.
    – VTT
    22 hours ago











  • How would that hypothetical feature work? Assume you can derive (if only privately) from a final class. Would virtual functions be treated as final?
    – curiousguy
    16 hours ago







8




8




Not having a virtual destructor does not prohibit or limit inheritance anyhow. It only makes ownership over object through a pointer to base class faulty. So that is not a reason for making std::string and most of other library classes final.
– VTT
22 hours ago





Not having a virtual destructor does not prohibit or limit inheritance anyhow. It only makes ownership over object through a pointer to base class faulty. So that is not a reason for making std::string and most of other library classes final.
– VTT
22 hours ago













How would that hypothetical feature work? Assume you can derive (if only privately) from a final class. Would virtual functions be treated as final?
– curiousguy
16 hours ago




How would that hypothetical feature work? Assume you can derive (if only privately) from a final class. Would virtual functions be treated as final?
– curiousguy
16 hours ago












2 Answers
2






active

oldest

votes


















13














Inheritance is inheritance. Accessibility is orthogonal to it. It only protects from statically treating the derived class as the base, outside the scope of the derived class. It makes no difference at runtime, and if private inheritance was allowed, you could write this:



struct C 
virtual void foo()
;

struct A final : C
virtual void foo()
;

void baz(A& ref) ref.foo();

class B: private A
virtual void foo()
void bar()
baz(*this);

;


Private inheritance doesn't stop you from using run-time polymorphism. If final is meant to fully prevent further overriding, then private inheritance must be included in the prohibition.






share|improve this answer






















  • Beautiful example, which reminds me the peculiar rule: if B is privately inherited from A, object of type B is still considered "an A" inside B itself! IMHO it would be better if the spec would not allow B in this case (of private inheritance) to override private virtuals of A, even without final! But this would be an extra rule for a very rare case I guess... and maybe not a good one at all. A better rule might be: be careful with private inheritance.
    – Amir Kirsh
    22 hours ago






  • 1




    @AmirKirsh - A subsection of the master rule. Be careful with C++ in general :)
    – StoryTeller
    22 hours ago






  • 2




    privately inherited from the master rule? :-)
    – Amir Kirsh
    22 hours ago











  • It could have been possible to have final only cap the polymorphic hierarchy. In that case, accessibility wouldn't have come into it either though.
    – Deduplicator
    18 hours ago










  • @Deduplicator - Could have. But the paper proposing it wanted to give class authors the tool to say "you can't inherit from this, period". That's not without merit either, and that's the direction the committee went with.
    – StoryTeller
    18 hours ago


















3














In addition to what Story Teller said, consider the reason for introducing final: It's supposed to help optimizations.



When a class is final, and you have a pointer to it, the compiler can prove which member function you are calling, even if it's virtual. If the class is not final, the pointer could actually be a pointer to some derived class, which could conceivably override the virtual method, forcing a full dynamic vtable lookup.



Whether the inheritance is private or not, it is always possible to create a base-class pointer. In the case of private inheritance, the creation of this base-class pointer would be restricted to the deriving class, the derived class, and any base of the derived class, which is still more code than the optimizer has available to make its decisions. As such, only forbidding all inheritance allows the virtual call optimizations to be made.






share|improve this answer




















    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53920492%2fwhy-does-c-forbid-private-inheritance-of-a-final-class%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    13














    Inheritance is inheritance. Accessibility is orthogonal to it. It only protects from statically treating the derived class as the base, outside the scope of the derived class. It makes no difference at runtime, and if private inheritance was allowed, you could write this:



    struct C 
    virtual void foo()
    ;

    struct A final : C
    virtual void foo()
    ;

    void baz(A& ref) ref.foo();

    class B: private A
    virtual void foo()
    void bar()
    baz(*this);

    ;


    Private inheritance doesn't stop you from using run-time polymorphism. If final is meant to fully prevent further overriding, then private inheritance must be included in the prohibition.






    share|improve this answer






















    • Beautiful example, which reminds me the peculiar rule: if B is privately inherited from A, object of type B is still considered "an A" inside B itself! IMHO it would be better if the spec would not allow B in this case (of private inheritance) to override private virtuals of A, even without final! But this would be an extra rule for a very rare case I guess... and maybe not a good one at all. A better rule might be: be careful with private inheritance.
      – Amir Kirsh
      22 hours ago






    • 1




      @AmirKirsh - A subsection of the master rule. Be careful with C++ in general :)
      – StoryTeller
      22 hours ago






    • 2




      privately inherited from the master rule? :-)
      – Amir Kirsh
      22 hours ago











    • It could have been possible to have final only cap the polymorphic hierarchy. In that case, accessibility wouldn't have come into it either though.
      – Deduplicator
      18 hours ago










    • @Deduplicator - Could have. But the paper proposing it wanted to give class authors the tool to say "you can't inherit from this, period". That's not without merit either, and that's the direction the committee went with.
      – StoryTeller
      18 hours ago















    13














    Inheritance is inheritance. Accessibility is orthogonal to it. It only protects from statically treating the derived class as the base, outside the scope of the derived class. It makes no difference at runtime, and if private inheritance was allowed, you could write this:



    struct C 
    virtual void foo()
    ;

    struct A final : C
    virtual void foo()
    ;

    void baz(A& ref) ref.foo();

    class B: private A
    virtual void foo()
    void bar()
    baz(*this);

    ;


    Private inheritance doesn't stop you from using run-time polymorphism. If final is meant to fully prevent further overriding, then private inheritance must be included in the prohibition.






    share|improve this answer






















    • Beautiful example, which reminds me the peculiar rule: if B is privately inherited from A, object of type B is still considered "an A" inside B itself! IMHO it would be better if the spec would not allow B in this case (of private inheritance) to override private virtuals of A, even without final! But this would be an extra rule for a very rare case I guess... and maybe not a good one at all. A better rule might be: be careful with private inheritance.
      – Amir Kirsh
      22 hours ago






    • 1




      @AmirKirsh - A subsection of the master rule. Be careful with C++ in general :)
      – StoryTeller
      22 hours ago






    • 2




      privately inherited from the master rule? :-)
      – Amir Kirsh
      22 hours ago











    • It could have been possible to have final only cap the polymorphic hierarchy. In that case, accessibility wouldn't have come into it either though.
      – Deduplicator
      18 hours ago










    • @Deduplicator - Could have. But the paper proposing it wanted to give class authors the tool to say "you can't inherit from this, period". That's not without merit either, and that's the direction the committee went with.
      – StoryTeller
      18 hours ago













    13












    13








    13






    Inheritance is inheritance. Accessibility is orthogonal to it. It only protects from statically treating the derived class as the base, outside the scope of the derived class. It makes no difference at runtime, and if private inheritance was allowed, you could write this:



    struct C 
    virtual void foo()
    ;

    struct A final : C
    virtual void foo()
    ;

    void baz(A& ref) ref.foo();

    class B: private A
    virtual void foo()
    void bar()
    baz(*this);

    ;


    Private inheritance doesn't stop you from using run-time polymorphism. If final is meant to fully prevent further overriding, then private inheritance must be included in the prohibition.






    share|improve this answer














    Inheritance is inheritance. Accessibility is orthogonal to it. It only protects from statically treating the derived class as the base, outside the scope of the derived class. It makes no difference at runtime, and if private inheritance was allowed, you could write this:



    struct C 
    virtual void foo()
    ;

    struct A final : C
    virtual void foo()
    ;

    void baz(A& ref) ref.foo();

    class B: private A
    virtual void foo()
    void bar()
    baz(*this);

    ;


    Private inheritance doesn't stop you from using run-time polymorphism. If final is meant to fully prevent further overriding, then private inheritance must be included in the prohibition.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 18 hours ago









    Boann

    36.7k1287121




    36.7k1287121










    answered 22 hours ago









    StoryTeller

    93.4k12187253




    93.4k12187253











    • Beautiful example, which reminds me the peculiar rule: if B is privately inherited from A, object of type B is still considered "an A" inside B itself! IMHO it would be better if the spec would not allow B in this case (of private inheritance) to override private virtuals of A, even without final! But this would be an extra rule for a very rare case I guess... and maybe not a good one at all. A better rule might be: be careful with private inheritance.
      – Amir Kirsh
      22 hours ago






    • 1




      @AmirKirsh - A subsection of the master rule. Be careful with C++ in general :)
      – StoryTeller
      22 hours ago






    • 2




      privately inherited from the master rule? :-)
      – Amir Kirsh
      22 hours ago











    • It could have been possible to have final only cap the polymorphic hierarchy. In that case, accessibility wouldn't have come into it either though.
      – Deduplicator
      18 hours ago










    • @Deduplicator - Could have. But the paper proposing it wanted to give class authors the tool to say "you can't inherit from this, period". That's not without merit either, and that's the direction the committee went with.
      – StoryTeller
      18 hours ago
















    • Beautiful example, which reminds me the peculiar rule: if B is privately inherited from A, object of type B is still considered "an A" inside B itself! IMHO it would be better if the spec would not allow B in this case (of private inheritance) to override private virtuals of A, even without final! But this would be an extra rule for a very rare case I guess... and maybe not a good one at all. A better rule might be: be careful with private inheritance.
      – Amir Kirsh
      22 hours ago






    • 1




      @AmirKirsh - A subsection of the master rule. Be careful with C++ in general :)
      – StoryTeller
      22 hours ago






    • 2




      privately inherited from the master rule? :-)
      – Amir Kirsh
      22 hours ago











    • It could have been possible to have final only cap the polymorphic hierarchy. In that case, accessibility wouldn't have come into it either though.
      – Deduplicator
      18 hours ago










    • @Deduplicator - Could have. But the paper proposing it wanted to give class authors the tool to say "you can't inherit from this, period". That's not without merit either, and that's the direction the committee went with.
      – StoryTeller
      18 hours ago















    Beautiful example, which reminds me the peculiar rule: if B is privately inherited from A, object of type B is still considered "an A" inside B itself! IMHO it would be better if the spec would not allow B in this case (of private inheritance) to override private virtuals of A, even without final! But this would be an extra rule for a very rare case I guess... and maybe not a good one at all. A better rule might be: be careful with private inheritance.
    – Amir Kirsh
    22 hours ago




    Beautiful example, which reminds me the peculiar rule: if B is privately inherited from A, object of type B is still considered "an A" inside B itself! IMHO it would be better if the spec would not allow B in this case (of private inheritance) to override private virtuals of A, even without final! But this would be an extra rule for a very rare case I guess... and maybe not a good one at all. A better rule might be: be careful with private inheritance.
    – Amir Kirsh
    22 hours ago




    1




    1




    @AmirKirsh - A subsection of the master rule. Be careful with C++ in general :)
    – StoryTeller
    22 hours ago




    @AmirKirsh - A subsection of the master rule. Be careful with C++ in general :)
    – StoryTeller
    22 hours ago




    2




    2




    privately inherited from the master rule? :-)
    – Amir Kirsh
    22 hours ago





    privately inherited from the master rule? :-)
    – Amir Kirsh
    22 hours ago













    It could have been possible to have final only cap the polymorphic hierarchy. In that case, accessibility wouldn't have come into it either though.
    – Deduplicator
    18 hours ago




    It could have been possible to have final only cap the polymorphic hierarchy. In that case, accessibility wouldn't have come into it either though.
    – Deduplicator
    18 hours ago












    @Deduplicator - Could have. But the paper proposing it wanted to give class authors the tool to say "you can't inherit from this, period". That's not without merit either, and that's the direction the committee went with.
    – StoryTeller
    18 hours ago




    @Deduplicator - Could have. But the paper proposing it wanted to give class authors the tool to say "you can't inherit from this, period". That's not without merit either, and that's the direction the committee went with.
    – StoryTeller
    18 hours ago













    3














    In addition to what Story Teller said, consider the reason for introducing final: It's supposed to help optimizations.



    When a class is final, and you have a pointer to it, the compiler can prove which member function you are calling, even if it's virtual. If the class is not final, the pointer could actually be a pointer to some derived class, which could conceivably override the virtual method, forcing a full dynamic vtable lookup.



    Whether the inheritance is private or not, it is always possible to create a base-class pointer. In the case of private inheritance, the creation of this base-class pointer would be restricted to the deriving class, the derived class, and any base of the derived class, which is still more code than the optimizer has available to make its decisions. As such, only forbidding all inheritance allows the virtual call optimizations to be made.






    share|improve this answer

























      3














      In addition to what Story Teller said, consider the reason for introducing final: It's supposed to help optimizations.



      When a class is final, and you have a pointer to it, the compiler can prove which member function you are calling, even if it's virtual. If the class is not final, the pointer could actually be a pointer to some derived class, which could conceivably override the virtual method, forcing a full dynamic vtable lookup.



      Whether the inheritance is private or not, it is always possible to create a base-class pointer. In the case of private inheritance, the creation of this base-class pointer would be restricted to the deriving class, the derived class, and any base of the derived class, which is still more code than the optimizer has available to make its decisions. As such, only forbidding all inheritance allows the virtual call optimizations to be made.






      share|improve this answer























        3












        3








        3






        In addition to what Story Teller said, consider the reason for introducing final: It's supposed to help optimizations.



        When a class is final, and you have a pointer to it, the compiler can prove which member function you are calling, even if it's virtual. If the class is not final, the pointer could actually be a pointer to some derived class, which could conceivably override the virtual method, forcing a full dynamic vtable lookup.



        Whether the inheritance is private or not, it is always possible to create a base-class pointer. In the case of private inheritance, the creation of this base-class pointer would be restricted to the deriving class, the derived class, and any base of the derived class, which is still more code than the optimizer has available to make its decisions. As such, only forbidding all inheritance allows the virtual call optimizations to be made.






        share|improve this answer












        In addition to what Story Teller said, consider the reason for introducing final: It's supposed to help optimizations.



        When a class is final, and you have a pointer to it, the compiler can prove which member function you are calling, even if it's virtual. If the class is not final, the pointer could actually be a pointer to some derived class, which could conceivably override the virtual method, forcing a full dynamic vtable lookup.



        Whether the inheritance is private or not, it is always possible to create a base-class pointer. In the case of private inheritance, the creation of this base-class pointer would be restricted to the deriving class, the derived class, and any base of the derived class, which is still more code than the optimizer has available to make its decisions. As such, only forbidding all inheritance allows the virtual call optimizations to be made.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 18 hours ago









        cmaster

        25.7k63778




        25.7k63778



























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid …


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid …


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53920492%2fwhy-does-c-forbid-private-inheritance-of-a-final-class%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Top Tejano songwriter Luis Silva dead of heart attack at 64

            ReactJS Fetched API data displays live - need Data displayed static

            政党