Difference between using non-virtual base class functions versus derived class non-implemented virtual...











up vote
2
down vote

favorite












This question is slightly related to What are the differences between overriding virtual functions and hiding non-virtual functions?, but I'm not asking about the technical details, rather about the usage of non-virtual and virtual functions.



Here's a little background. Let's say I have a base class A and two derived classes B and C



#include <iostream>

class A {
public:
A() {};
virtual void foo() { std::cout << "foo() called in An"; };
virtual void bar() { std::cout << "bar() called from An"; };
void xorp() { std::cout << "xorp() called from An"; };
virtual ~A() {};
};

class B : public A {
public:
B() {};
virtual ~B() {};
virtual void foo() override { std::cout << "foo() called in Bn"; };
//virtual void bar() override not implemented in B, using A::bar();
};

class C : public A {
public:
C() {};
virtual ~C() {};
virtual void foo() override { std::cout << "foo() called in Cn"; };
//virtual bar() override not implemented in C, using A::bar();
};

int main() {
A a{};
B b{};
C c{};

a.foo(); //calls A::foo()
a.bar(); //calls A::bar()
a.xorp(); //calls non-virtual A::xorp()

b.foo(); //calls virtual overridden function B::foo()
b.bar(); //calls virtual non-overridden function A::bar()
b.xorp(); //calls non-virtual A::xorp()

c.foo(); //calls virtual overridden function C::foo()
c.bar(); //calls virtual non-overridden function A::bar()
c.xorp(); //calls non-virtual A::xorp()

return 0;
}


This outputs, as expected, the following:



foo() called in A
bar() called from A
xorp() called from A
foo() called in B
bar() called from A
xorp() called from A
foo() called in C
bar() called from A
xorp() called from A


If I leave the virtual function bar() unimplemented in the derived classes, any call to bar() in the derived classes B and C gets resolved to A::bar(). xorp(), which is a non-virtual function, can also be called from the derived classes as either b.xorp() or b.A::xorp().



If I were to implement a xorp() in B, for example, it would effectively hide the A::xorp() and a call to b.xorp() would actually be a call to b.B::xorp().



Which brings me to my question, using the example above. Let's say I have a helper function that the derived classes need for their implementation.



Is there a difference between having the helper function be a non-virtual member function (like xorp()), versus the helper function being a virtual function that the derived classes do not override (bar())?



Reading through this presentation on class object layout and VTABLEs (https://www.cs.bgu.ac.il/~asharf/SPL/Inheritance.pptx, slides 28-35) I could not really spot a difference, since both non-virtual and non-overridden virtual functions point to the same place (i.e the function in the base class)



Could anyone give me an example where these two approaches would produce different results, or if there is a caveat that I have not spotted?










share|improve this question
























  • No difference. But a derived class might override the function. The usual caveat is that you don't know when it happens, who did it and why he chose to do so. And can break your class doing it. These are high risk factors that you have to think through when you design. Hard to do correctly. Luckily there is a very simple solution, declare the class final. That might produce a phone call some time in the future, but it is one that eliminates all those risks.
    – Hans Passant
    Nov 11 at 12:54










  • You don't use virtual inheritance here.
    – curiousguy
    Nov 13 at 5:02















up vote
2
down vote

favorite












This question is slightly related to What are the differences between overriding virtual functions and hiding non-virtual functions?, but I'm not asking about the technical details, rather about the usage of non-virtual and virtual functions.



Here's a little background. Let's say I have a base class A and two derived classes B and C



#include <iostream>

class A {
public:
A() {};
virtual void foo() { std::cout << "foo() called in An"; };
virtual void bar() { std::cout << "bar() called from An"; };
void xorp() { std::cout << "xorp() called from An"; };
virtual ~A() {};
};

class B : public A {
public:
B() {};
virtual ~B() {};
virtual void foo() override { std::cout << "foo() called in Bn"; };
//virtual void bar() override not implemented in B, using A::bar();
};

class C : public A {
public:
C() {};
virtual ~C() {};
virtual void foo() override { std::cout << "foo() called in Cn"; };
//virtual bar() override not implemented in C, using A::bar();
};

int main() {
A a{};
B b{};
C c{};

a.foo(); //calls A::foo()
a.bar(); //calls A::bar()
a.xorp(); //calls non-virtual A::xorp()

b.foo(); //calls virtual overridden function B::foo()
b.bar(); //calls virtual non-overridden function A::bar()
b.xorp(); //calls non-virtual A::xorp()

c.foo(); //calls virtual overridden function C::foo()
c.bar(); //calls virtual non-overridden function A::bar()
c.xorp(); //calls non-virtual A::xorp()

return 0;
}


This outputs, as expected, the following:



foo() called in A
bar() called from A
xorp() called from A
foo() called in B
bar() called from A
xorp() called from A
foo() called in C
bar() called from A
xorp() called from A


If I leave the virtual function bar() unimplemented in the derived classes, any call to bar() in the derived classes B and C gets resolved to A::bar(). xorp(), which is a non-virtual function, can also be called from the derived classes as either b.xorp() or b.A::xorp().



If I were to implement a xorp() in B, for example, it would effectively hide the A::xorp() and a call to b.xorp() would actually be a call to b.B::xorp().



Which brings me to my question, using the example above. Let's say I have a helper function that the derived classes need for their implementation.



Is there a difference between having the helper function be a non-virtual member function (like xorp()), versus the helper function being a virtual function that the derived classes do not override (bar())?



Reading through this presentation on class object layout and VTABLEs (https://www.cs.bgu.ac.il/~asharf/SPL/Inheritance.pptx, slides 28-35) I could not really spot a difference, since both non-virtual and non-overridden virtual functions point to the same place (i.e the function in the base class)



Could anyone give me an example where these two approaches would produce different results, or if there is a caveat that I have not spotted?










share|improve this question
























  • No difference. But a derived class might override the function. The usual caveat is that you don't know when it happens, who did it and why he chose to do so. And can break your class doing it. These are high risk factors that you have to think through when you design. Hard to do correctly. Luckily there is a very simple solution, declare the class final. That might produce a phone call some time in the future, but it is one that eliminates all those risks.
    – Hans Passant
    Nov 11 at 12:54










  • You don't use virtual inheritance here.
    – curiousguy
    Nov 13 at 5:02













up vote
2
down vote

favorite









up vote
2
down vote

favorite











This question is slightly related to What are the differences between overriding virtual functions and hiding non-virtual functions?, but I'm not asking about the technical details, rather about the usage of non-virtual and virtual functions.



Here's a little background. Let's say I have a base class A and two derived classes B and C



#include <iostream>

class A {
public:
A() {};
virtual void foo() { std::cout << "foo() called in An"; };
virtual void bar() { std::cout << "bar() called from An"; };
void xorp() { std::cout << "xorp() called from An"; };
virtual ~A() {};
};

class B : public A {
public:
B() {};
virtual ~B() {};
virtual void foo() override { std::cout << "foo() called in Bn"; };
//virtual void bar() override not implemented in B, using A::bar();
};

class C : public A {
public:
C() {};
virtual ~C() {};
virtual void foo() override { std::cout << "foo() called in Cn"; };
//virtual bar() override not implemented in C, using A::bar();
};

int main() {
A a{};
B b{};
C c{};

a.foo(); //calls A::foo()
a.bar(); //calls A::bar()
a.xorp(); //calls non-virtual A::xorp()

b.foo(); //calls virtual overridden function B::foo()
b.bar(); //calls virtual non-overridden function A::bar()
b.xorp(); //calls non-virtual A::xorp()

c.foo(); //calls virtual overridden function C::foo()
c.bar(); //calls virtual non-overridden function A::bar()
c.xorp(); //calls non-virtual A::xorp()

return 0;
}


This outputs, as expected, the following:



foo() called in A
bar() called from A
xorp() called from A
foo() called in B
bar() called from A
xorp() called from A
foo() called in C
bar() called from A
xorp() called from A


If I leave the virtual function bar() unimplemented in the derived classes, any call to bar() in the derived classes B and C gets resolved to A::bar(). xorp(), which is a non-virtual function, can also be called from the derived classes as either b.xorp() or b.A::xorp().



If I were to implement a xorp() in B, for example, it would effectively hide the A::xorp() and a call to b.xorp() would actually be a call to b.B::xorp().



Which brings me to my question, using the example above. Let's say I have a helper function that the derived classes need for their implementation.



Is there a difference between having the helper function be a non-virtual member function (like xorp()), versus the helper function being a virtual function that the derived classes do not override (bar())?



Reading through this presentation on class object layout and VTABLEs (https://www.cs.bgu.ac.il/~asharf/SPL/Inheritance.pptx, slides 28-35) I could not really spot a difference, since both non-virtual and non-overridden virtual functions point to the same place (i.e the function in the base class)



Could anyone give me an example where these two approaches would produce different results, or if there is a caveat that I have not spotted?










share|improve this question















This question is slightly related to What are the differences between overriding virtual functions and hiding non-virtual functions?, but I'm not asking about the technical details, rather about the usage of non-virtual and virtual functions.



Here's a little background. Let's say I have a base class A and two derived classes B and C



#include <iostream>

class A {
public:
A() {};
virtual void foo() { std::cout << "foo() called in An"; };
virtual void bar() { std::cout << "bar() called from An"; };
void xorp() { std::cout << "xorp() called from An"; };
virtual ~A() {};
};

class B : public A {
public:
B() {};
virtual ~B() {};
virtual void foo() override { std::cout << "foo() called in Bn"; };
//virtual void bar() override not implemented in B, using A::bar();
};

class C : public A {
public:
C() {};
virtual ~C() {};
virtual void foo() override { std::cout << "foo() called in Cn"; };
//virtual bar() override not implemented in C, using A::bar();
};

int main() {
A a{};
B b{};
C c{};

a.foo(); //calls A::foo()
a.bar(); //calls A::bar()
a.xorp(); //calls non-virtual A::xorp()

b.foo(); //calls virtual overridden function B::foo()
b.bar(); //calls virtual non-overridden function A::bar()
b.xorp(); //calls non-virtual A::xorp()

c.foo(); //calls virtual overridden function C::foo()
c.bar(); //calls virtual non-overridden function A::bar()
c.xorp(); //calls non-virtual A::xorp()

return 0;
}


This outputs, as expected, the following:



foo() called in A
bar() called from A
xorp() called from A
foo() called in B
bar() called from A
xorp() called from A
foo() called in C
bar() called from A
xorp() called from A


If I leave the virtual function bar() unimplemented in the derived classes, any call to bar() in the derived classes B and C gets resolved to A::bar(). xorp(), which is a non-virtual function, can also be called from the derived classes as either b.xorp() or b.A::xorp().



If I were to implement a xorp() in B, for example, it would effectively hide the A::xorp() and a call to b.xorp() would actually be a call to b.B::xorp().



Which brings me to my question, using the example above. Let's say I have a helper function that the derived classes need for their implementation.



Is there a difference between having the helper function be a non-virtual member function (like xorp()), versus the helper function being a virtual function that the derived classes do not override (bar())?



Reading through this presentation on class object layout and VTABLEs (https://www.cs.bgu.ac.il/~asharf/SPL/Inheritance.pptx, slides 28-35) I could not really spot a difference, since both non-virtual and non-overridden virtual functions point to the same place (i.e the function in the base class)



Could anyone give me an example where these two approaches would produce different results, or if there is a caveat that I have not spotted?







c++ override virtual-functions name-hiding






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 13 at 9:55









curiousguy

4,50622940




4,50622940










asked Nov 11 at 12:13









NotAProgrammer

132




132












  • No difference. But a derived class might override the function. The usual caveat is that you don't know when it happens, who did it and why he chose to do so. And can break your class doing it. These are high risk factors that you have to think through when you design. Hard to do correctly. Luckily there is a very simple solution, declare the class final. That might produce a phone call some time in the future, but it is one that eliminates all those risks.
    – Hans Passant
    Nov 11 at 12:54










  • You don't use virtual inheritance here.
    – curiousguy
    Nov 13 at 5:02


















  • No difference. But a derived class might override the function. The usual caveat is that you don't know when it happens, who did it and why he chose to do so. And can break your class doing it. These are high risk factors that you have to think through when you design. Hard to do correctly. Luckily there is a very simple solution, declare the class final. That might produce a phone call some time in the future, but it is one that eliminates all those risks.
    – Hans Passant
    Nov 11 at 12:54










  • You don't use virtual inheritance here.
    – curiousguy
    Nov 13 at 5:02
















No difference. But a derived class might override the function. The usual caveat is that you don't know when it happens, who did it and why he chose to do so. And can break your class doing it. These are high risk factors that you have to think through when you design. Hard to do correctly. Luckily there is a very simple solution, declare the class final. That might produce a phone call some time in the future, but it is one that eliminates all those risks.
– Hans Passant
Nov 11 at 12:54




No difference. But a derived class might override the function. The usual caveat is that you don't know when it happens, who did it and why he chose to do so. And can break your class doing it. These are high risk factors that you have to think through when you design. Hard to do correctly. Luckily there is a very simple solution, declare the class final. That might produce a phone call some time in the future, but it is one that eliminates all those risks.
– Hans Passant
Nov 11 at 12:54












You don't use virtual inheritance here.
– curiousguy
Nov 13 at 5:02




You don't use virtual inheritance here.
– curiousguy
Nov 13 at 5:02












2 Answers
2






active

oldest

votes

















up vote
3
down vote



accepted










The flaw in your example is that you aren't using polymorphism. You operate on all the objects directly. You won't notice anything related to overriding, because none of the calls need to be resolved dynamically. And if the call is not resolved dynamically, there is absolutely no difference between virtual functions and non-virtual ones. To see the difference, use a helper free function:



void baz(A& a) {
a.foo();
a.bar();
a.xorp();
}

int main() {
// As before
baz(a);
baz(b);
baz(c);
}


Now you should be able to see a noticeable difference in how the calls to foo, bar and baz are resolved. In particular...




If I were to implement a xorp() in B, for example, it would effectively hide the A::xorp() and a call to b.xorp() would actually be a call to b.B::xorp().




... will no longer be true inside baz.






share|improve this answer























  • "The flaw in your example" - I think the example is specifically constructed to ask if the compiler will do anything differently when polymorphism is not used.
    – HostileFork
    Nov 11 at 12:38






  • 1




    @HostileFork - I dunno, the OP asked "Could anyone give me an example where these two approaches would produce different results, or if there is a caveat that I have not spotted?", which to me implies they are not sure about their example too. But if you think another answer applies, by all means, write it up. Answer diversity is SO's strength.
    – StoryTeller
    Nov 11 at 12:41






  • 1




    Thanks, the example with baz() definitely helped me a lot to understand what I was trying to ask better.
    – NotAProgrammer
    Nov 11 at 13:50


















up vote
0
down vote














Is there a difference between having the helper function be a non-virtual member function (like xorp()), versus the helper function being a virtual function that the derived classes do not override (bar())?




If you mark a method virtual but you never override it, it's behavior will be equivalent to if you'd never marked it virtual. The relationship to other methods it calls in the object is not affected.



That isn't to say there aren't still "differences".



It certainly conveys a difference in intent to those reading the code. If your xorp() method is not virtual--but relies on virtual methods to implement its behavior--then people will understand "xorpiness" as having certain fixed properties. They would likely try to avoid a redefinition of xorp() in any derived classes, and know to only affect the xorpiness indirectly through defining the virtual methods it depends on.



Plus, the compiler can't always know if you're going to use a virtual override or not. So it can't optimize out the extra code for virtual dispatch--even if you aren't "taking advantage" of it. (Occasionally it can, like if you have a class you never derive from and don't export it...the virtual may just get dropped.)



And with exported classes you expect other people to use: just because you never overrode a method doesn't mean someone else won't. Unless you use final and prevent derivation of your objects (which isn't considered terribly friendly to do, unless you've got really good reasons). So if you make something virtual, the ability is there, and once someone else adds an override then yes--there will be a difference at that point.






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',
    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%2f53248642%2fdifference-between-using-non-virtual-base-class-functions-versus-derived-class-n%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








    up vote
    3
    down vote



    accepted










    The flaw in your example is that you aren't using polymorphism. You operate on all the objects directly. You won't notice anything related to overriding, because none of the calls need to be resolved dynamically. And if the call is not resolved dynamically, there is absolutely no difference between virtual functions and non-virtual ones. To see the difference, use a helper free function:



    void baz(A& a) {
    a.foo();
    a.bar();
    a.xorp();
    }

    int main() {
    // As before
    baz(a);
    baz(b);
    baz(c);
    }


    Now you should be able to see a noticeable difference in how the calls to foo, bar and baz are resolved. In particular...




    If I were to implement a xorp() in B, for example, it would effectively hide the A::xorp() and a call to b.xorp() would actually be a call to b.B::xorp().




    ... will no longer be true inside baz.






    share|improve this answer























    • "The flaw in your example" - I think the example is specifically constructed to ask if the compiler will do anything differently when polymorphism is not used.
      – HostileFork
      Nov 11 at 12:38






    • 1




      @HostileFork - I dunno, the OP asked "Could anyone give me an example where these two approaches would produce different results, or if there is a caveat that I have not spotted?", which to me implies they are not sure about their example too. But if you think another answer applies, by all means, write it up. Answer diversity is SO's strength.
      – StoryTeller
      Nov 11 at 12:41






    • 1




      Thanks, the example with baz() definitely helped me a lot to understand what I was trying to ask better.
      – NotAProgrammer
      Nov 11 at 13:50















    up vote
    3
    down vote



    accepted










    The flaw in your example is that you aren't using polymorphism. You operate on all the objects directly. You won't notice anything related to overriding, because none of the calls need to be resolved dynamically. And if the call is not resolved dynamically, there is absolutely no difference between virtual functions and non-virtual ones. To see the difference, use a helper free function:



    void baz(A& a) {
    a.foo();
    a.bar();
    a.xorp();
    }

    int main() {
    // As before
    baz(a);
    baz(b);
    baz(c);
    }


    Now you should be able to see a noticeable difference in how the calls to foo, bar and baz are resolved. In particular...




    If I were to implement a xorp() in B, for example, it would effectively hide the A::xorp() and a call to b.xorp() would actually be a call to b.B::xorp().




    ... will no longer be true inside baz.






    share|improve this answer























    • "The flaw in your example" - I think the example is specifically constructed to ask if the compiler will do anything differently when polymorphism is not used.
      – HostileFork
      Nov 11 at 12:38






    • 1




      @HostileFork - I dunno, the OP asked "Could anyone give me an example where these two approaches would produce different results, or if there is a caveat that I have not spotted?", which to me implies they are not sure about their example too. But if you think another answer applies, by all means, write it up. Answer diversity is SO's strength.
      – StoryTeller
      Nov 11 at 12:41






    • 1




      Thanks, the example with baz() definitely helped me a lot to understand what I was trying to ask better.
      – NotAProgrammer
      Nov 11 at 13:50













    up vote
    3
    down vote



    accepted







    up vote
    3
    down vote



    accepted






    The flaw in your example is that you aren't using polymorphism. You operate on all the objects directly. You won't notice anything related to overriding, because none of the calls need to be resolved dynamically. And if the call is not resolved dynamically, there is absolutely no difference between virtual functions and non-virtual ones. To see the difference, use a helper free function:



    void baz(A& a) {
    a.foo();
    a.bar();
    a.xorp();
    }

    int main() {
    // As before
    baz(a);
    baz(b);
    baz(c);
    }


    Now you should be able to see a noticeable difference in how the calls to foo, bar and baz are resolved. In particular...




    If I were to implement a xorp() in B, for example, it would effectively hide the A::xorp() and a call to b.xorp() would actually be a call to b.B::xorp().




    ... will no longer be true inside baz.






    share|improve this answer














    The flaw in your example is that you aren't using polymorphism. You operate on all the objects directly. You won't notice anything related to overriding, because none of the calls need to be resolved dynamically. And if the call is not resolved dynamically, there is absolutely no difference between virtual functions and non-virtual ones. To see the difference, use a helper free function:



    void baz(A& a) {
    a.foo();
    a.bar();
    a.xorp();
    }

    int main() {
    // As before
    baz(a);
    baz(b);
    baz(c);
    }


    Now you should be able to see a noticeable difference in how the calls to foo, bar and baz are resolved. In particular...




    If I were to implement a xorp() in B, for example, it would effectively hide the A::xorp() and a call to b.xorp() would actually be a call to b.B::xorp().




    ... will no longer be true inside baz.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 11 at 12:50

























    answered Nov 11 at 12:36









    StoryTeller

    90.9k12181247




    90.9k12181247












    • "The flaw in your example" - I think the example is specifically constructed to ask if the compiler will do anything differently when polymorphism is not used.
      – HostileFork
      Nov 11 at 12:38






    • 1




      @HostileFork - I dunno, the OP asked "Could anyone give me an example where these two approaches would produce different results, or if there is a caveat that I have not spotted?", which to me implies they are not sure about their example too. But if you think another answer applies, by all means, write it up. Answer diversity is SO's strength.
      – StoryTeller
      Nov 11 at 12:41






    • 1




      Thanks, the example with baz() definitely helped me a lot to understand what I was trying to ask better.
      – NotAProgrammer
      Nov 11 at 13:50


















    • "The flaw in your example" - I think the example is specifically constructed to ask if the compiler will do anything differently when polymorphism is not used.
      – HostileFork
      Nov 11 at 12:38






    • 1




      @HostileFork - I dunno, the OP asked "Could anyone give me an example where these two approaches would produce different results, or if there is a caveat that I have not spotted?", which to me implies they are not sure about their example too. But if you think another answer applies, by all means, write it up. Answer diversity is SO's strength.
      – StoryTeller
      Nov 11 at 12:41






    • 1




      Thanks, the example with baz() definitely helped me a lot to understand what I was trying to ask better.
      – NotAProgrammer
      Nov 11 at 13:50
















    "The flaw in your example" - I think the example is specifically constructed to ask if the compiler will do anything differently when polymorphism is not used.
    – HostileFork
    Nov 11 at 12:38




    "The flaw in your example" - I think the example is specifically constructed to ask if the compiler will do anything differently when polymorphism is not used.
    – HostileFork
    Nov 11 at 12:38




    1




    1




    @HostileFork - I dunno, the OP asked "Could anyone give me an example where these two approaches would produce different results, or if there is a caveat that I have not spotted?", which to me implies they are not sure about their example too. But if you think another answer applies, by all means, write it up. Answer diversity is SO's strength.
    – StoryTeller
    Nov 11 at 12:41




    @HostileFork - I dunno, the OP asked "Could anyone give me an example where these two approaches would produce different results, or if there is a caveat that I have not spotted?", which to me implies they are not sure about their example too. But if you think another answer applies, by all means, write it up. Answer diversity is SO's strength.
    – StoryTeller
    Nov 11 at 12:41




    1




    1




    Thanks, the example with baz() definitely helped me a lot to understand what I was trying to ask better.
    – NotAProgrammer
    Nov 11 at 13:50




    Thanks, the example with baz() definitely helped me a lot to understand what I was trying to ask better.
    – NotAProgrammer
    Nov 11 at 13:50












    up vote
    0
    down vote














    Is there a difference between having the helper function be a non-virtual member function (like xorp()), versus the helper function being a virtual function that the derived classes do not override (bar())?




    If you mark a method virtual but you never override it, it's behavior will be equivalent to if you'd never marked it virtual. The relationship to other methods it calls in the object is not affected.



    That isn't to say there aren't still "differences".



    It certainly conveys a difference in intent to those reading the code. If your xorp() method is not virtual--but relies on virtual methods to implement its behavior--then people will understand "xorpiness" as having certain fixed properties. They would likely try to avoid a redefinition of xorp() in any derived classes, and know to only affect the xorpiness indirectly through defining the virtual methods it depends on.



    Plus, the compiler can't always know if you're going to use a virtual override or not. So it can't optimize out the extra code for virtual dispatch--even if you aren't "taking advantage" of it. (Occasionally it can, like if you have a class you never derive from and don't export it...the virtual may just get dropped.)



    And with exported classes you expect other people to use: just because you never overrode a method doesn't mean someone else won't. Unless you use final and prevent derivation of your objects (which isn't considered terribly friendly to do, unless you've got really good reasons). So if you make something virtual, the ability is there, and once someone else adds an override then yes--there will be a difference at that point.






    share|improve this answer



























      up vote
      0
      down vote














      Is there a difference between having the helper function be a non-virtual member function (like xorp()), versus the helper function being a virtual function that the derived classes do not override (bar())?




      If you mark a method virtual but you never override it, it's behavior will be equivalent to if you'd never marked it virtual. The relationship to other methods it calls in the object is not affected.



      That isn't to say there aren't still "differences".



      It certainly conveys a difference in intent to those reading the code. If your xorp() method is not virtual--but relies on virtual methods to implement its behavior--then people will understand "xorpiness" as having certain fixed properties. They would likely try to avoid a redefinition of xorp() in any derived classes, and know to only affect the xorpiness indirectly through defining the virtual methods it depends on.



      Plus, the compiler can't always know if you're going to use a virtual override or not. So it can't optimize out the extra code for virtual dispatch--even if you aren't "taking advantage" of it. (Occasionally it can, like if you have a class you never derive from and don't export it...the virtual may just get dropped.)



      And with exported classes you expect other people to use: just because you never overrode a method doesn't mean someone else won't. Unless you use final and prevent derivation of your objects (which isn't considered terribly friendly to do, unless you've got really good reasons). So if you make something virtual, the ability is there, and once someone else adds an override then yes--there will be a difference at that point.






      share|improve this answer

























        up vote
        0
        down vote










        up vote
        0
        down vote










        Is there a difference between having the helper function be a non-virtual member function (like xorp()), versus the helper function being a virtual function that the derived classes do not override (bar())?




        If you mark a method virtual but you never override it, it's behavior will be equivalent to if you'd never marked it virtual. The relationship to other methods it calls in the object is not affected.



        That isn't to say there aren't still "differences".



        It certainly conveys a difference in intent to those reading the code. If your xorp() method is not virtual--but relies on virtual methods to implement its behavior--then people will understand "xorpiness" as having certain fixed properties. They would likely try to avoid a redefinition of xorp() in any derived classes, and know to only affect the xorpiness indirectly through defining the virtual methods it depends on.



        Plus, the compiler can't always know if you're going to use a virtual override or not. So it can't optimize out the extra code for virtual dispatch--even if you aren't "taking advantage" of it. (Occasionally it can, like if you have a class you never derive from and don't export it...the virtual may just get dropped.)



        And with exported classes you expect other people to use: just because you never overrode a method doesn't mean someone else won't. Unless you use final and prevent derivation of your objects (which isn't considered terribly friendly to do, unless you've got really good reasons). So if you make something virtual, the ability is there, and once someone else adds an override then yes--there will be a difference at that point.






        share|improve this answer















        Is there a difference between having the helper function be a non-virtual member function (like xorp()), versus the helper function being a virtual function that the derived classes do not override (bar())?




        If you mark a method virtual but you never override it, it's behavior will be equivalent to if you'd never marked it virtual. The relationship to other methods it calls in the object is not affected.



        That isn't to say there aren't still "differences".



        It certainly conveys a difference in intent to those reading the code. If your xorp() method is not virtual--but relies on virtual methods to implement its behavior--then people will understand "xorpiness" as having certain fixed properties. They would likely try to avoid a redefinition of xorp() in any derived classes, and know to only affect the xorpiness indirectly through defining the virtual methods it depends on.



        Plus, the compiler can't always know if you're going to use a virtual override or not. So it can't optimize out the extra code for virtual dispatch--even if you aren't "taking advantage" of it. (Occasionally it can, like if you have a class you never derive from and don't export it...the virtual may just get dropped.)



        And with exported classes you expect other people to use: just because you never overrode a method doesn't mean someone else won't. Unless you use final and prevent derivation of your objects (which isn't considered terribly friendly to do, unless you've got really good reasons). So if you make something virtual, the ability is there, and once someone else adds an override then yes--there will be a difference at that point.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 11 at 13:09

























        answered Nov 11 at 12:58









        HostileFork

        24.7k775131




        24.7k775131






























            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%2f53248642%2fdifference-between-using-non-virtual-base-class-functions-versus-derived-class-n%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

            Full-time equivalent

            Bicuculline

            さくらももこ