Is it valid to “hide” a base class virtual function by making it pure virtual in derived classes?












7















Consider the example:



#include <iostream>

class A {
public:
virtual void f();
};

void A::f()
{
std::cout << "f() from An";
}

class B: public A {
public:
virtual void f() = 0;
};

class C: public B {
public:
void f();
};

void C::f()
{
std::cout << "f() from Cn";
}

int main()
{
C o;
o.f();
}


A::f() implementation is "hidden" from class C, which provides its own implementation for f() - effectively making A::f() more or less pointless. I see little value in such class hierarchy design, but my question whether this is a valid C++ or just "works" (such as undefined behaviours)?










share|improve this question























  • Though it's "hidden" you can still use A::f() to call A's implementation (for example : o.A::f();).

    – François Andrieux
    37 mins ago








  • 2





    Consider using override when overriding a base class' virtual member function to avoid errors.

    – François Andrieux
    36 mins ago











  • @FrançoisAndrieux I understand A::f() can be called directly. I just wondered if this is a valid thing. Thanks for the override suggestion which I often forget!

    – usr
    15 mins ago
















7















Consider the example:



#include <iostream>

class A {
public:
virtual void f();
};

void A::f()
{
std::cout << "f() from An";
}

class B: public A {
public:
virtual void f() = 0;
};

class C: public B {
public:
void f();
};

void C::f()
{
std::cout << "f() from Cn";
}

int main()
{
C o;
o.f();
}


A::f() implementation is "hidden" from class C, which provides its own implementation for f() - effectively making A::f() more or less pointless. I see little value in such class hierarchy design, but my question whether this is a valid C++ or just "works" (such as undefined behaviours)?










share|improve this question























  • Though it's "hidden" you can still use A::f() to call A's implementation (for example : o.A::f();).

    – François Andrieux
    37 mins ago








  • 2





    Consider using override when overriding a base class' virtual member function to avoid errors.

    – François Andrieux
    36 mins ago











  • @FrançoisAndrieux I understand A::f() can be called directly. I just wondered if this is a valid thing. Thanks for the override suggestion which I often forget!

    – usr
    15 mins ago














7












7








7


1






Consider the example:



#include <iostream>

class A {
public:
virtual void f();
};

void A::f()
{
std::cout << "f() from An";
}

class B: public A {
public:
virtual void f() = 0;
};

class C: public B {
public:
void f();
};

void C::f()
{
std::cout << "f() from Cn";
}

int main()
{
C o;
o.f();
}


A::f() implementation is "hidden" from class C, which provides its own implementation for f() - effectively making A::f() more or less pointless. I see little value in such class hierarchy design, but my question whether this is a valid C++ or just "works" (such as undefined behaviours)?










share|improve this question














Consider the example:



#include <iostream>

class A {
public:
virtual void f();
};

void A::f()
{
std::cout << "f() from An";
}

class B: public A {
public:
virtual void f() = 0;
};

class C: public B {
public:
void f();
};

void C::f()
{
std::cout << "f() from Cn";
}

int main()
{
C o;
o.f();
}


A::f() implementation is "hidden" from class C, which provides its own implementation for f() - effectively making A::f() more or less pointless. I see little value in such class hierarchy design, but my question whether this is a valid C++ or just "works" (such as undefined behaviours)?







c++ c++11 language-lawyer






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 39 mins ago









usrusr

13.9k32139




13.9k32139













  • Though it's "hidden" you can still use A::f() to call A's implementation (for example : o.A::f();).

    – François Andrieux
    37 mins ago








  • 2





    Consider using override when overriding a base class' virtual member function to avoid errors.

    – François Andrieux
    36 mins ago











  • @FrançoisAndrieux I understand A::f() can be called directly. I just wondered if this is a valid thing. Thanks for the override suggestion which I often forget!

    – usr
    15 mins ago



















  • Though it's "hidden" you can still use A::f() to call A's implementation (for example : o.A::f();).

    – François Andrieux
    37 mins ago








  • 2





    Consider using override when overriding a base class' virtual member function to avoid errors.

    – François Andrieux
    36 mins ago











  • @FrançoisAndrieux I understand A::f() can be called directly. I just wondered if this is a valid thing. Thanks for the override suggestion which I often forget!

    – usr
    15 mins ago

















Though it's "hidden" you can still use A::f() to call A's implementation (for example : o.A::f();).

– François Andrieux
37 mins ago







Though it's "hidden" you can still use A::f() to call A's implementation (for example : o.A::f();).

– François Andrieux
37 mins ago






2




2





Consider using override when overriding a base class' virtual member function to avoid errors.

– François Andrieux
36 mins ago





Consider using override when overriding a base class' virtual member function to avoid errors.

– François Andrieux
36 mins ago













@FrançoisAndrieux I understand A::f() can be called directly. I just wondered if this is a valid thing. Thanks for the override suggestion which I often forget!

– usr
15 mins ago





@FrançoisAndrieux I understand A::f() can be called directly. I just wondered if this is a valid thing. Thanks for the override suggestion which I often forget!

– usr
15 mins ago












5 Answers
5






active

oldest

votes


















6














It is clearly allowed and supported by the standard (cf, for example, this online C++ standard draft), and thus clearly not undefined behaviour:




10.4 Abstract classes



5 [ Note: An abstract class can be derived from a class that is not
abstract, and a pure virtual function may override a virtual function
which is not pure. — end note ]




The effect is that your class B becomes abstract and any subclass - if it shall not be abstract, too - must define f() then; the implementation in class A can still be invoked through A::f(), such that it is - from the perspective of reusing the implementation - not pointless.






share|improve this answer































    2















    my question whether this is a valid C++ or just "works" (such as undefined behaviours)?




    The behaviour of the program is well defined.




    effectively making A::f() more or less pointless.




    Of course, if you never call a function, then defining the function is unnecessary indeed. To clarify, the function would have to be declared pure virtual if you did choose to omit the definition (the opposite is not true; you can define a pure virtual function).






    share|improve this answer

































      2














      This will safely achieve the goal of requiring the author of C to provide an implementation for f().



      I would query why this is needed — if the base implementation is not "valid" in your design then why does it exist, and/or why is it virtual?



      They can still invoke A::f(), anyway, so whether this can be deemed "hiding" is open to debate.






      share|improve this answer
























      • It's unclear what the OP thinks is being hidden. Seems quite clear what it does and I don't see anything being hidden.

        – doug
        8 mins ago











      • I agree with your question - but a colleague argued this increases "safety" (i.e., it forces C to provide an implementation and avoids calling A::f() accidentally while allowing A::f() to be called directly if needed). bTW, the "hidden" is used for want of a better word. Hiding isn't really important to my question. Thanks.

        – usr
        7 mins ago



















      1














      This is valid and well-defined C++.



      It can occasionally be useful if you want to force a user of your class to implement a method that's already implemented in a base class (and don't want to use a different name which would be a more obvious choice). GUI libraries implementing operating system message pumps are one application.






      share|improve this answer































        1














        As far as I can see there's no undefined behavior = 0 only means that derived classes must override it. But you can still provide an out-of-line definition for that function in the same class.






        share|improve this answer
























        • Remove "As far as I can see". Grow a pair!

          – Bathsheba
          12 secs ago











        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%2f54330926%2fis-it-valid-to-hide-a-base-class-virtual-function-by-making-it-pure-virtual-in%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        5 Answers
        5






        active

        oldest

        votes








        5 Answers
        5






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        6














        It is clearly allowed and supported by the standard (cf, for example, this online C++ standard draft), and thus clearly not undefined behaviour:




        10.4 Abstract classes



        5 [ Note: An abstract class can be derived from a class that is not
        abstract, and a pure virtual function may override a virtual function
        which is not pure. — end note ]




        The effect is that your class B becomes abstract and any subclass - if it shall not be abstract, too - must define f() then; the implementation in class A can still be invoked through A::f(), such that it is - from the perspective of reusing the implementation - not pointless.






        share|improve this answer




























          6














          It is clearly allowed and supported by the standard (cf, for example, this online C++ standard draft), and thus clearly not undefined behaviour:




          10.4 Abstract classes



          5 [ Note: An abstract class can be derived from a class that is not
          abstract, and a pure virtual function may override a virtual function
          which is not pure. — end note ]




          The effect is that your class B becomes abstract and any subclass - if it shall not be abstract, too - must define f() then; the implementation in class A can still be invoked through A::f(), such that it is - from the perspective of reusing the implementation - not pointless.






          share|improve this answer


























            6












            6








            6







            It is clearly allowed and supported by the standard (cf, for example, this online C++ standard draft), and thus clearly not undefined behaviour:




            10.4 Abstract classes



            5 [ Note: An abstract class can be derived from a class that is not
            abstract, and a pure virtual function may override a virtual function
            which is not pure. — end note ]




            The effect is that your class B becomes abstract and any subclass - if it shall not be abstract, too - must define f() then; the implementation in class A can still be invoked through A::f(), such that it is - from the perspective of reusing the implementation - not pointless.






            share|improve this answer













            It is clearly allowed and supported by the standard (cf, for example, this online C++ standard draft), and thus clearly not undefined behaviour:




            10.4 Abstract classes



            5 [ Note: An abstract class can be derived from a class that is not
            abstract, and a pure virtual function may override a virtual function
            which is not pure. — end note ]




            The effect is that your class B becomes abstract and any subclass - if it shall not be abstract, too - must define f() then; the implementation in class A can still be invoked through A::f(), such that it is - from the perspective of reusing the implementation - not pointless.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered 24 mins ago









            Stephan LechnerStephan Lechner

            27.6k22140




            27.6k22140

























                2















                my question whether this is a valid C++ or just "works" (such as undefined behaviours)?




                The behaviour of the program is well defined.




                effectively making A::f() more or less pointless.




                Of course, if you never call a function, then defining the function is unnecessary indeed. To clarify, the function would have to be declared pure virtual if you did choose to omit the definition (the opposite is not true; you can define a pure virtual function).






                share|improve this answer






























                  2















                  my question whether this is a valid C++ or just "works" (such as undefined behaviours)?




                  The behaviour of the program is well defined.




                  effectively making A::f() more or less pointless.




                  Of course, if you never call a function, then defining the function is unnecessary indeed. To clarify, the function would have to be declared pure virtual if you did choose to omit the definition (the opposite is not true; you can define a pure virtual function).






                  share|improve this answer




























                    2












                    2








                    2








                    my question whether this is a valid C++ or just "works" (such as undefined behaviours)?




                    The behaviour of the program is well defined.




                    effectively making A::f() more or less pointless.




                    Of course, if you never call a function, then defining the function is unnecessary indeed. To clarify, the function would have to be declared pure virtual if you did choose to omit the definition (the opposite is not true; you can define a pure virtual function).






                    share|improve this answer
















                    my question whether this is a valid C++ or just "works" (such as undefined behaviours)?




                    The behaviour of the program is well defined.




                    effectively making A::f() more or less pointless.




                    Of course, if you never call a function, then defining the function is unnecessary indeed. To clarify, the function would have to be declared pure virtual if you did choose to omit the definition (the opposite is not true; you can define a pure virtual function).







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited 21 mins ago

























                    answered 27 mins ago









                    eerorikaeerorika

                    79k556119




                    79k556119























                        2














                        This will safely achieve the goal of requiring the author of C to provide an implementation for f().



                        I would query why this is needed — if the base implementation is not "valid" in your design then why does it exist, and/or why is it virtual?



                        They can still invoke A::f(), anyway, so whether this can be deemed "hiding" is open to debate.






                        share|improve this answer
























                        • It's unclear what the OP thinks is being hidden. Seems quite clear what it does and I don't see anything being hidden.

                          – doug
                          8 mins ago











                        • I agree with your question - but a colleague argued this increases "safety" (i.e., it forces C to provide an implementation and avoids calling A::f() accidentally while allowing A::f() to be called directly if needed). bTW, the "hidden" is used for want of a better word. Hiding isn't really important to my question. Thanks.

                          – usr
                          7 mins ago
















                        2














                        This will safely achieve the goal of requiring the author of C to provide an implementation for f().



                        I would query why this is needed — if the base implementation is not "valid" in your design then why does it exist, and/or why is it virtual?



                        They can still invoke A::f(), anyway, so whether this can be deemed "hiding" is open to debate.






                        share|improve this answer
























                        • It's unclear what the OP thinks is being hidden. Seems quite clear what it does and I don't see anything being hidden.

                          – doug
                          8 mins ago











                        • I agree with your question - but a colleague argued this increases "safety" (i.e., it forces C to provide an implementation and avoids calling A::f() accidentally while allowing A::f() to be called directly if needed). bTW, the "hidden" is used for want of a better word. Hiding isn't really important to my question. Thanks.

                          – usr
                          7 mins ago














                        2












                        2








                        2







                        This will safely achieve the goal of requiring the author of C to provide an implementation for f().



                        I would query why this is needed — if the base implementation is not "valid" in your design then why does it exist, and/or why is it virtual?



                        They can still invoke A::f(), anyway, so whether this can be deemed "hiding" is open to debate.






                        share|improve this answer













                        This will safely achieve the goal of requiring the author of C to provide an implementation for f().



                        I would query why this is needed — if the base implementation is not "valid" in your design then why does it exist, and/or why is it virtual?



                        They can still invoke A::f(), anyway, so whether this can be deemed "hiding" is open to debate.







                        share|improve this answer












                        share|improve this answer



                        share|improve this answer










                        answered 21 mins ago









                        Lightness Races in OrbitLightness Races in Orbit

                        287k51467792




                        287k51467792













                        • It's unclear what the OP thinks is being hidden. Seems quite clear what it does and I don't see anything being hidden.

                          – doug
                          8 mins ago











                        • I agree with your question - but a colleague argued this increases "safety" (i.e., it forces C to provide an implementation and avoids calling A::f() accidentally while allowing A::f() to be called directly if needed). bTW, the "hidden" is used for want of a better word. Hiding isn't really important to my question. Thanks.

                          – usr
                          7 mins ago



















                        • It's unclear what the OP thinks is being hidden. Seems quite clear what it does and I don't see anything being hidden.

                          – doug
                          8 mins ago











                        • I agree with your question - but a colleague argued this increases "safety" (i.e., it forces C to provide an implementation and avoids calling A::f() accidentally while allowing A::f() to be called directly if needed). bTW, the "hidden" is used for want of a better word. Hiding isn't really important to my question. Thanks.

                          – usr
                          7 mins ago

















                        It's unclear what the OP thinks is being hidden. Seems quite clear what it does and I don't see anything being hidden.

                        – doug
                        8 mins ago





                        It's unclear what the OP thinks is being hidden. Seems quite clear what it does and I don't see anything being hidden.

                        – doug
                        8 mins ago













                        I agree with your question - but a colleague argued this increases "safety" (i.e., it forces C to provide an implementation and avoids calling A::f() accidentally while allowing A::f() to be called directly if needed). bTW, the "hidden" is used for want of a better word. Hiding isn't really important to my question. Thanks.

                        – usr
                        7 mins ago





                        I agree with your question - but a colleague argued this increases "safety" (i.e., it forces C to provide an implementation and avoids calling A::f() accidentally while allowing A::f() to be called directly if needed). bTW, the "hidden" is used for want of a better word. Hiding isn't really important to my question. Thanks.

                        – usr
                        7 mins ago











                        1














                        This is valid and well-defined C++.



                        It can occasionally be useful if you want to force a user of your class to implement a method that's already implemented in a base class (and don't want to use a different name which would be a more obvious choice). GUI libraries implementing operating system message pumps are one application.






                        share|improve this answer




























                          1














                          This is valid and well-defined C++.



                          It can occasionally be useful if you want to force a user of your class to implement a method that's already implemented in a base class (and don't want to use a different name which would be a more obvious choice). GUI libraries implementing operating system message pumps are one application.






                          share|improve this answer


























                            1












                            1








                            1







                            This is valid and well-defined C++.



                            It can occasionally be useful if you want to force a user of your class to implement a method that's already implemented in a base class (and don't want to use a different name which would be a more obvious choice). GUI libraries implementing operating system message pumps are one application.






                            share|improve this answer













                            This is valid and well-defined C++.



                            It can occasionally be useful if you want to force a user of your class to implement a method that's already implemented in a base class (and don't want to use a different name which would be a more obvious choice). GUI libraries implementing operating system message pumps are one application.







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered 23 mins ago









                            BathshebaBathsheba

                            177k27253376




                            177k27253376























                                1














                                As far as I can see there's no undefined behavior = 0 only means that derived classes must override it. But you can still provide an out-of-line definition for that function in the same class.






                                share|improve this answer
























                                • Remove "As far as I can see". Grow a pair!

                                  – Bathsheba
                                  12 secs ago
















                                1














                                As far as I can see there's no undefined behavior = 0 only means that derived classes must override it. But you can still provide an out-of-line definition for that function in the same class.






                                share|improve this answer
























                                • Remove "As far as I can see". Grow a pair!

                                  – Bathsheba
                                  12 secs ago














                                1












                                1








                                1







                                As far as I can see there's no undefined behavior = 0 only means that derived classes must override it. But you can still provide an out-of-line definition for that function in the same class.






                                share|improve this answer













                                As far as I can see there's no undefined behavior = 0 only means that derived classes must override it. But you can still provide an out-of-line definition for that function in the same class.







                                share|improve this answer












                                share|improve this answer



                                share|improve this answer










                                answered 20 mins ago









                                SebastianSebastian

                                111




                                111













                                • Remove "As far as I can see". Grow a pair!

                                  – Bathsheba
                                  12 secs ago



















                                • Remove "As far as I can see". Grow a pair!

                                  – Bathsheba
                                  12 secs ago

















                                Remove "As far as I can see". Grow a pair!

                                – Bathsheba
                                12 secs ago





                                Remove "As far as I can see". Grow a pair!

                                – Bathsheba
                                12 secs ago


















                                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.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54330926%2fis-it-valid-to-hide-a-base-class-virtual-function-by-making-it-pure-virtual-in%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

                                Aikido

                                Tivadar Csontváry Kosztka

                                Metroo de Marsejlo