The logic of invoking virtual functions is not clear (or it is method hiding?)When to use virtual destructors?What is the performance cost of having a virtual method in a C++ class?Can I call a base class's virtual function if I'm overriding it?Calling virtual functions inside constructorsWhy do we need virtual functions in C++?C++: inheriting overloaded non-virtual method and virtual method both with the same name causes problemC++ “virtual” keyword for functions in derived classes. Is it necessary?Confusion regarding name hiding and virtual functionsIs the 'override' keyword just a check for a overridden virtual method?Virtual method being called instead of derived methodWhy does this virtual method return true?

Metal that glows when near pieces of itself

Would combining A* with a flocking algorithm be too performance-heavy?

Why didn’t Doctor Strange stay in the original winning timeline?

Importing ES6 module in LWC project (sfdx)

Overwrite file only if data

Why doesn't mathematics collapse even though humans quite often make mistakes in their proofs?

Are illustrations in novels frowned upon?

Can I submit a paper under an alias so as to avoid trouble in my country?

Why we don't have vaccination against all diseases which are caused by microbes?

Can you be convicted for being a murderer twice?

Can my boyfriend, who lives in the UK and has a Polish passport, visit me in the USA?

Why don't politicians push for fossil fuel reduction by pointing out their scarcity?

Don't understand MOSFET as amplifier

How do you call it when two celestial bodies come as close to each other as they will in their current orbits?

In an emergency, how do I find and share my position?

Is there a known non-euclidean geometry where two concentric circles of different radii can intersect? (as in the novel "The Universe Between")

How does turbine efficiency compare with internal combustion engines if all the turbine power is converted to mechanical energy?

Why don't we use Cavea-B

Sleeping solo in a double sleeping bag

How to persuade recruiters to send me the Job Description?

What is this shrub with berries?

The teacher logged me in as administrator for doing a short task, is the whole system now compromised?

Defense against attacks using dictionaries

Co-author responds to email by mistake cc'ing the EiC



The logic of invoking virtual functions is not clear (or it is method hiding?)


When to use virtual destructors?What is the performance cost of having a virtual method in a C++ class?Can I call a base class's virtual function if I'm overriding it?Calling virtual functions inside constructorsWhy do we need virtual functions in C++?C++: inheriting overloaded non-virtual method and virtual method both with the same name causes problemC++ “virtual” keyword for functions in derived classes. Is it necessary?Confusion regarding name hiding and virtual functionsIs the 'override' keyword just a check for a overridden virtual method?Virtual method being called instead of derived methodWhy does this virtual method return true?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








7















(tested on msvc2017)



struct AAA

virtual float run(int arg)

return 5.5f;

;

struct BBB : AAA

virtual bool run(double arg)

return false;

;

struct CCC : BBB

virtual float run(int arg)

return 7.7f;


virtual bool run(double arg)

return true;

;


CCC c;
BBB* pb = &c;
pb->run(5); // call CCC::run(double arg), WHY??
pb->run((int)5); // call CCC::run(double arg), WHY??


Why does pb->run(5) call only CCC::run(double arg), but not CCC::run(int arg)?



Does the virtual method of a child class with a different signature overlap the interface of the base class?










share|improve this question









New contributor



dimasafo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • 1





    You have misconceptions about function signatures and how these are matching, that's all. Voted to close.

    – πάντα ῥεῖ
    8 hours ago






  • 8





    @πάνταῥεῖ Close for what reason?

    – melpomene
    8 hours ago











  • This is not a question about signatures having to match for the virtual method in the derived class. It's phrased confusingly, but that's not what's asked here.

    – Sam Varshavchik
    8 hours ago











  • I'm sure we have a few name hiding dupes though

    – Lightness Races in Orbit
    7 hours ago











  • I understand! The call works because int can be implicitly converted to double. (otherwise it would cause compilation error) If we replace AAA::run(int) and CCC::run(int) to respectively AAA::run(CustomType) and CCC::run(CustomType) - it would cause compilation error

    – dimasafo
    7 hours ago


















7















(tested on msvc2017)



struct AAA

virtual float run(int arg)

return 5.5f;

;

struct BBB : AAA

virtual bool run(double arg)

return false;

;

struct CCC : BBB

virtual float run(int arg)

return 7.7f;


virtual bool run(double arg)

return true;

;


CCC c;
BBB* pb = &c;
pb->run(5); // call CCC::run(double arg), WHY??
pb->run((int)5); // call CCC::run(double arg), WHY??


Why does pb->run(5) call only CCC::run(double arg), but not CCC::run(int arg)?



Does the virtual method of a child class with a different signature overlap the interface of the base class?










share|improve this question









New contributor



dimasafo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • 1





    You have misconceptions about function signatures and how these are matching, that's all. Voted to close.

    – πάντα ῥεῖ
    8 hours ago






  • 8





    @πάνταῥεῖ Close for what reason?

    – melpomene
    8 hours ago











  • This is not a question about signatures having to match for the virtual method in the derived class. It's phrased confusingly, but that's not what's asked here.

    – Sam Varshavchik
    8 hours ago











  • I'm sure we have a few name hiding dupes though

    – Lightness Races in Orbit
    7 hours ago











  • I understand! The call works because int can be implicitly converted to double. (otherwise it would cause compilation error) If we replace AAA::run(int) and CCC::run(int) to respectively AAA::run(CustomType) and CCC::run(CustomType) - it would cause compilation error

    – dimasafo
    7 hours ago














7












7








7


2






(tested on msvc2017)



struct AAA

virtual float run(int arg)

return 5.5f;

;

struct BBB : AAA

virtual bool run(double arg)

return false;

;

struct CCC : BBB

virtual float run(int arg)

return 7.7f;


virtual bool run(double arg)

return true;

;


CCC c;
BBB* pb = &c;
pb->run(5); // call CCC::run(double arg), WHY??
pb->run((int)5); // call CCC::run(double arg), WHY??


Why does pb->run(5) call only CCC::run(double arg), but not CCC::run(int arg)?



Does the virtual method of a child class with a different signature overlap the interface of the base class?










share|improve this question









New contributor



dimasafo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











(tested on msvc2017)



struct AAA

virtual float run(int arg)

return 5.5f;

;

struct BBB : AAA

virtual bool run(double arg)

return false;

;

struct CCC : BBB

virtual float run(int arg)

return 7.7f;


virtual bool run(double arg)

return true;

;


CCC c;
BBB* pb = &c;
pb->run(5); // call CCC::run(double arg), WHY??
pb->run((int)5); // call CCC::run(double arg), WHY??


Why does pb->run(5) call only CCC::run(double arg), but not CCC::run(int arg)?



Does the virtual method of a child class with a different signature overlap the interface of the base class?







c++ class inheritance overriding virtual






share|improve this question









New contributor



dimasafo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.










share|improve this question









New contributor



dimasafo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








share|improve this question




share|improve this question








edited 7 hours ago









Vlad from Moscow

150k14 gold badges92 silver badges192 bronze badges




150k14 gold badges92 silver badges192 bronze badges






New contributor



dimasafo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








asked 8 hours ago









dimasafodimasafo

443 bronze badges




443 bronze badges




New contributor



dimasafo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




New contributor




dimasafo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












  • 1





    You have misconceptions about function signatures and how these are matching, that's all. Voted to close.

    – πάντα ῥεῖ
    8 hours ago






  • 8





    @πάνταῥεῖ Close for what reason?

    – melpomene
    8 hours ago











  • This is not a question about signatures having to match for the virtual method in the derived class. It's phrased confusingly, but that's not what's asked here.

    – Sam Varshavchik
    8 hours ago











  • I'm sure we have a few name hiding dupes though

    – Lightness Races in Orbit
    7 hours ago











  • I understand! The call works because int can be implicitly converted to double. (otherwise it would cause compilation error) If we replace AAA::run(int) and CCC::run(int) to respectively AAA::run(CustomType) and CCC::run(CustomType) - it would cause compilation error

    – dimasafo
    7 hours ago













  • 1





    You have misconceptions about function signatures and how these are matching, that's all. Voted to close.

    – πάντα ῥεῖ
    8 hours ago






  • 8





    @πάνταῥεῖ Close for what reason?

    – melpomene
    8 hours ago











  • This is not a question about signatures having to match for the virtual method in the derived class. It's phrased confusingly, but that's not what's asked here.

    – Sam Varshavchik
    8 hours ago











  • I'm sure we have a few name hiding dupes though

    – Lightness Races in Orbit
    7 hours ago











  • I understand! The call works because int can be implicitly converted to double. (otherwise it would cause compilation error) If we replace AAA::run(int) and CCC::run(int) to respectively AAA::run(CustomType) and CCC::run(CustomType) - it would cause compilation error

    – dimasafo
    7 hours ago








1




1





You have misconceptions about function signatures and how these are matching, that's all. Voted to close.

– πάντα ῥεῖ
8 hours ago





You have misconceptions about function signatures and how these are matching, that's all. Voted to close.

– πάντα ῥεῖ
8 hours ago




8




8





@πάνταῥεῖ Close for what reason?

– melpomene
8 hours ago





@πάνταῥεῖ Close for what reason?

– melpomene
8 hours ago













This is not a question about signatures having to match for the virtual method in the derived class. It's phrased confusingly, but that's not what's asked here.

– Sam Varshavchik
8 hours ago





This is not a question about signatures having to match for the virtual method in the derived class. It's phrased confusingly, but that's not what's asked here.

– Sam Varshavchik
8 hours ago













I'm sure we have a few name hiding dupes though

– Lightness Races in Orbit
7 hours ago





I'm sure we have a few name hiding dupes though

– Lightness Races in Orbit
7 hours ago













I understand! The call works because int can be implicitly converted to double. (otherwise it would cause compilation error) If we replace AAA::run(int) and CCC::run(int) to respectively AAA::run(CustomType) and CCC::run(CustomType) - it would cause compilation error

– dimasafo
7 hours ago






I understand! The call works because int can be implicitly converted to double. (otherwise it would cause compilation error) If we replace AAA::run(int) and CCC::run(int) to respectively AAA::run(CustomType) and CCC::run(CustomType) - it would cause compilation error

– dimasafo
7 hours ago













2 Answers
2






active

oldest

votes


















6














All is simple.



The class BBB has in fact two virtual functions. One is declared in its base class AAA



struct AAA

virtual float run(int arg)

return 5.5f;

;


And other is declared in the class BBB itself.



struct BBB : AAA

virtual bool run(double arg)

return false;

;


The function declared in the class BBB hides the function declared in the class AAA. (Any name declared in a derived class hides an entity with the same name declared in the base class of the derived class)



In the class CCC the both functions are overriden.



These function calls



pb->run(5); // call CCC::run(double arg), WHY?? 
pb->run((int)5); // call CCC::run(double arg), WHY??


do not differ because their arguments have the type int.



The static type of the pointer pb is BBB *. So the compiler searches the name run in the class BBB.



Within the class only one function with this name is visible. It is the function declared in the class



virtual bool run(double arg)

return false;



So the compiler runs this virtual function with this signature but invokes it using the table of virtual function pointers defined for the class CCC because the dynamic type of the pointer pb is CCC *.



You could make the function declared in the class AAA visible within the class BBB by means of the using declaration. For example



struct BBB : AAA

using AAA:: run;
virtual bool run(double arg)

return false;

;


In this case the declaration of the function (declared in the class AAA) would be also a member declaration inside the class BBB. That is the class BBB will have declarations of two overloaded distinct virtual functions.



Here is a demonstrative program



#include <iostream>

struct AAA

virtual float run(int arg)

return 5.5f;

;

struct BBB : AAA

using AAA:: run;
virtual bool run(double arg)

return false;

;

struct CCC : BBB

virtual float run(int arg)

return 7.7f;


virtual bool run(double arg)

return true;

;

int main()

CCC c;
BBB* pb = &c;
std::cout << pb->run(5) << 'n';
std::cout << pb->run(5.6 ) << 'n';

return 0;



Its output is



7.7
1


To make the situation with the member declarations in a derived class and in its base class consider a similar situation with block scopes.



Here is a demonstrative program



#include <iostream>

void f( int ) std::cout << "void f( int )n";
void f( double ) std::cout << "void f( double )n";

int main()

void f( double );

f( 5 );
f( 5.5 );

return 0;



The inner declaration of the function f in the block scope of the function main hides the other declaration of the function in the global scope.



The program output is



void f( double )
void f( double )





share|improve this answer



























  • @LightnessRacesinOrbit Thanks. I updated the post.

    – Vlad from Moscow
    7 hours ago











  • >>So the compiler searches the name run in the class BBB. Does it mean than compiler searches only by name but not with full prototype?

    – dimasafo
    7 hours ago






  • 2





    @dimasafo It searches the name. Then it determines that the name belongs to a function and uses the function declaration to call its corresponding definition that is overriden in the class CCC.

    – Vlad from Moscow
    7 hours ago


















6














When you do



struct BBB : AAA

virtual bool run(double arg)

return false;

;


run has a different signature from run in AAA. This means that BBB::run(double) will hide AAA::run(int). Since it does, the only run that you can call from BBB is bool run(double arg). When you do



pb->run(5);


it finds bool BBB::run(double arg) as that is the only function you can call statically from a BBB and then virtual dispatch kicks in calling CCC::run(double)




In order to get the int version of the function to be called, you need to bring the int version into BBB. You can do this by writing one, or you could use using AAA::run; to import it in. Doing either of those will make pb->run(5); call the int version of run from CCC.




Don't forget, when playing with polymorphism you should declare the top level destructor (AAA's in this case) to be virtual. This allows you to delete objects correctly when using dynamic allocation. For full details see: When to use virtual destructors?






share|improve this answer



























  • >>This means that BBB::run(double) will hide AAA::run(int) I thought it will hide medhod only for BBB but not for CCC. In fact it is unclear for me. So the vtable will contain only one function. Right?

    – dimasafo
    8 hours ago












  • @JeJo: Through an AAA*, you would find float run(int) (and only that one, no possibility to call bool run(double))

    – Ben Voigt
    8 hours ago











  • @dimasafo Can't say about that. The reason the int version isn't called is because BBB can only call BBB::run(double), so that is the fucntion that virtual dispatch happens on. The int version is never considered.

    – NathanOliver
    8 hours ago











  • @dimasafo pb is a BBB, so only BBB's functions are considered. If you change pb to be a AAA* then the int version is called.

    – NathanOliver
    8 hours ago







  • 1





    Feels like using override here would have helped out a lot.

    – François Andrieux
    7 hours 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
);



);






dimasafo is a new contributor. Be nice, and check out our Code of Conduct.









draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f57577757%2fthe-logic-of-invoking-virtual-functions-is-not-clear-or-it-is-method-hiding%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









6














All is simple.



The class BBB has in fact two virtual functions. One is declared in its base class AAA



struct AAA

virtual float run(int arg)

return 5.5f;

;


And other is declared in the class BBB itself.



struct BBB : AAA

virtual bool run(double arg)

return false;

;


The function declared in the class BBB hides the function declared in the class AAA. (Any name declared in a derived class hides an entity with the same name declared in the base class of the derived class)



In the class CCC the both functions are overriden.



These function calls



pb->run(5); // call CCC::run(double arg), WHY?? 
pb->run((int)5); // call CCC::run(double arg), WHY??


do not differ because their arguments have the type int.



The static type of the pointer pb is BBB *. So the compiler searches the name run in the class BBB.



Within the class only one function with this name is visible. It is the function declared in the class



virtual bool run(double arg)

return false;



So the compiler runs this virtual function with this signature but invokes it using the table of virtual function pointers defined for the class CCC because the dynamic type of the pointer pb is CCC *.



You could make the function declared in the class AAA visible within the class BBB by means of the using declaration. For example



struct BBB : AAA

using AAA:: run;
virtual bool run(double arg)

return false;

;


In this case the declaration of the function (declared in the class AAA) would be also a member declaration inside the class BBB. That is the class BBB will have declarations of two overloaded distinct virtual functions.



Here is a demonstrative program



#include <iostream>

struct AAA

virtual float run(int arg)

return 5.5f;

;

struct BBB : AAA

using AAA:: run;
virtual bool run(double arg)

return false;

;

struct CCC : BBB

virtual float run(int arg)

return 7.7f;


virtual bool run(double arg)

return true;

;

int main()

CCC c;
BBB* pb = &c;
std::cout << pb->run(5) << 'n';
std::cout << pb->run(5.6 ) << 'n';

return 0;



Its output is



7.7
1


To make the situation with the member declarations in a derived class and in its base class consider a similar situation with block scopes.



Here is a demonstrative program



#include <iostream>

void f( int ) std::cout << "void f( int )n";
void f( double ) std::cout << "void f( double )n";

int main()

void f( double );

f( 5 );
f( 5.5 );

return 0;



The inner declaration of the function f in the block scope of the function main hides the other declaration of the function in the global scope.



The program output is



void f( double )
void f( double )





share|improve this answer



























  • @LightnessRacesinOrbit Thanks. I updated the post.

    – Vlad from Moscow
    7 hours ago











  • >>So the compiler searches the name run in the class BBB. Does it mean than compiler searches only by name but not with full prototype?

    – dimasafo
    7 hours ago






  • 2





    @dimasafo It searches the name. Then it determines that the name belongs to a function and uses the function declaration to call its corresponding definition that is overriden in the class CCC.

    – Vlad from Moscow
    7 hours ago















6














All is simple.



The class BBB has in fact two virtual functions. One is declared in its base class AAA



struct AAA

virtual float run(int arg)

return 5.5f;

;


And other is declared in the class BBB itself.



struct BBB : AAA

virtual bool run(double arg)

return false;

;


The function declared in the class BBB hides the function declared in the class AAA. (Any name declared in a derived class hides an entity with the same name declared in the base class of the derived class)



In the class CCC the both functions are overriden.



These function calls



pb->run(5); // call CCC::run(double arg), WHY?? 
pb->run((int)5); // call CCC::run(double arg), WHY??


do not differ because their arguments have the type int.



The static type of the pointer pb is BBB *. So the compiler searches the name run in the class BBB.



Within the class only one function with this name is visible. It is the function declared in the class



virtual bool run(double arg)

return false;



So the compiler runs this virtual function with this signature but invokes it using the table of virtual function pointers defined for the class CCC because the dynamic type of the pointer pb is CCC *.



You could make the function declared in the class AAA visible within the class BBB by means of the using declaration. For example



struct BBB : AAA

using AAA:: run;
virtual bool run(double arg)

return false;

;


In this case the declaration of the function (declared in the class AAA) would be also a member declaration inside the class BBB. That is the class BBB will have declarations of two overloaded distinct virtual functions.



Here is a demonstrative program



#include <iostream>

struct AAA

virtual float run(int arg)

return 5.5f;

;

struct BBB : AAA

using AAA:: run;
virtual bool run(double arg)

return false;

;

struct CCC : BBB

virtual float run(int arg)

return 7.7f;


virtual bool run(double arg)

return true;

;

int main()

CCC c;
BBB* pb = &c;
std::cout << pb->run(5) << 'n';
std::cout << pb->run(5.6 ) << 'n';

return 0;



Its output is



7.7
1


To make the situation with the member declarations in a derived class and in its base class consider a similar situation with block scopes.



Here is a demonstrative program



#include <iostream>

void f( int ) std::cout << "void f( int )n";
void f( double ) std::cout << "void f( double )n";

int main()

void f( double );

f( 5 );
f( 5.5 );

return 0;



The inner declaration of the function f in the block scope of the function main hides the other declaration of the function in the global scope.



The program output is



void f( double )
void f( double )





share|improve this answer



























  • @LightnessRacesinOrbit Thanks. I updated the post.

    – Vlad from Moscow
    7 hours ago











  • >>So the compiler searches the name run in the class BBB. Does it mean than compiler searches only by name but not with full prototype?

    – dimasafo
    7 hours ago






  • 2





    @dimasafo It searches the name. Then it determines that the name belongs to a function and uses the function declaration to call its corresponding definition that is overriden in the class CCC.

    – Vlad from Moscow
    7 hours ago













6












6








6







All is simple.



The class BBB has in fact two virtual functions. One is declared in its base class AAA



struct AAA

virtual float run(int arg)

return 5.5f;

;


And other is declared in the class BBB itself.



struct BBB : AAA

virtual bool run(double arg)

return false;

;


The function declared in the class BBB hides the function declared in the class AAA. (Any name declared in a derived class hides an entity with the same name declared in the base class of the derived class)



In the class CCC the both functions are overriden.



These function calls



pb->run(5); // call CCC::run(double arg), WHY?? 
pb->run((int)5); // call CCC::run(double arg), WHY??


do not differ because their arguments have the type int.



The static type of the pointer pb is BBB *. So the compiler searches the name run in the class BBB.



Within the class only one function with this name is visible. It is the function declared in the class



virtual bool run(double arg)

return false;



So the compiler runs this virtual function with this signature but invokes it using the table of virtual function pointers defined for the class CCC because the dynamic type of the pointer pb is CCC *.



You could make the function declared in the class AAA visible within the class BBB by means of the using declaration. For example



struct BBB : AAA

using AAA:: run;
virtual bool run(double arg)

return false;

;


In this case the declaration of the function (declared in the class AAA) would be also a member declaration inside the class BBB. That is the class BBB will have declarations of two overloaded distinct virtual functions.



Here is a demonstrative program



#include <iostream>

struct AAA

virtual float run(int arg)

return 5.5f;

;

struct BBB : AAA

using AAA:: run;
virtual bool run(double arg)

return false;

;

struct CCC : BBB

virtual float run(int arg)

return 7.7f;


virtual bool run(double arg)

return true;

;

int main()

CCC c;
BBB* pb = &c;
std::cout << pb->run(5) << 'n';
std::cout << pb->run(5.6 ) << 'n';

return 0;



Its output is



7.7
1


To make the situation with the member declarations in a derived class and in its base class consider a similar situation with block scopes.



Here is a demonstrative program



#include <iostream>

void f( int ) std::cout << "void f( int )n";
void f( double ) std::cout << "void f( double )n";

int main()

void f( double );

f( 5 );
f( 5.5 );

return 0;



The inner declaration of the function f in the block scope of the function main hides the other declaration of the function in the global scope.



The program output is



void f( double )
void f( double )





share|improve this answer















All is simple.



The class BBB has in fact two virtual functions. One is declared in its base class AAA



struct AAA

virtual float run(int arg)

return 5.5f;

;


And other is declared in the class BBB itself.



struct BBB : AAA

virtual bool run(double arg)

return false;

;


The function declared in the class BBB hides the function declared in the class AAA. (Any name declared in a derived class hides an entity with the same name declared in the base class of the derived class)



In the class CCC the both functions are overriden.



These function calls



pb->run(5); // call CCC::run(double arg), WHY?? 
pb->run((int)5); // call CCC::run(double arg), WHY??


do not differ because their arguments have the type int.



The static type of the pointer pb is BBB *. So the compiler searches the name run in the class BBB.



Within the class only one function with this name is visible. It is the function declared in the class



virtual bool run(double arg)

return false;



So the compiler runs this virtual function with this signature but invokes it using the table of virtual function pointers defined for the class CCC because the dynamic type of the pointer pb is CCC *.



You could make the function declared in the class AAA visible within the class BBB by means of the using declaration. For example



struct BBB : AAA

using AAA:: run;
virtual bool run(double arg)

return false;

;


In this case the declaration of the function (declared in the class AAA) would be also a member declaration inside the class BBB. That is the class BBB will have declarations of two overloaded distinct virtual functions.



Here is a demonstrative program



#include <iostream>

struct AAA

virtual float run(int arg)

return 5.5f;

;

struct BBB : AAA

using AAA:: run;
virtual bool run(double arg)

return false;

;

struct CCC : BBB

virtual float run(int arg)

return 7.7f;


virtual bool run(double arg)

return true;

;

int main()

CCC c;
BBB* pb = &c;
std::cout << pb->run(5) << 'n';
std::cout << pb->run(5.6 ) << 'n';

return 0;



Its output is



7.7
1


To make the situation with the member declarations in a derived class and in its base class consider a similar situation with block scopes.



Here is a demonstrative program



#include <iostream>

void f( int ) std::cout << "void f( int )n";
void f( double ) std::cout << "void f( double )n";

int main()

void f( double );

f( 5 );
f( 5.5 );

return 0;



The inner declaration of the function f in the block scope of the function main hides the other declaration of the function in the global scope.



The program output is



void f( double )
void f( double )






share|improve this answer














share|improve this answer



share|improve this answer








edited 7 hours ago

























answered 8 hours ago









Vlad from MoscowVlad from Moscow

150k14 gold badges92 silver badges192 bronze badges




150k14 gold badges92 silver badges192 bronze badges















  • @LightnessRacesinOrbit Thanks. I updated the post.

    – Vlad from Moscow
    7 hours ago











  • >>So the compiler searches the name run in the class BBB. Does it mean than compiler searches only by name but not with full prototype?

    – dimasafo
    7 hours ago






  • 2





    @dimasafo It searches the name. Then it determines that the name belongs to a function and uses the function declaration to call its corresponding definition that is overriden in the class CCC.

    – Vlad from Moscow
    7 hours ago

















  • @LightnessRacesinOrbit Thanks. I updated the post.

    – Vlad from Moscow
    7 hours ago











  • >>So the compiler searches the name run in the class BBB. Does it mean than compiler searches only by name but not with full prototype?

    – dimasafo
    7 hours ago






  • 2





    @dimasafo It searches the name. Then it determines that the name belongs to a function and uses the function declaration to call its corresponding definition that is overriden in the class CCC.

    – Vlad from Moscow
    7 hours ago
















@LightnessRacesinOrbit Thanks. I updated the post.

– Vlad from Moscow
7 hours ago





@LightnessRacesinOrbit Thanks. I updated the post.

– Vlad from Moscow
7 hours ago













>>So the compiler searches the name run in the class BBB. Does it mean than compiler searches only by name but not with full prototype?

– dimasafo
7 hours ago





>>So the compiler searches the name run in the class BBB. Does it mean than compiler searches only by name but not with full prototype?

– dimasafo
7 hours ago




2




2





@dimasafo It searches the name. Then it determines that the name belongs to a function and uses the function declaration to call its corresponding definition that is overriden in the class CCC.

– Vlad from Moscow
7 hours ago





@dimasafo It searches the name. Then it determines that the name belongs to a function and uses the function declaration to call its corresponding definition that is overriden in the class CCC.

– Vlad from Moscow
7 hours ago













6














When you do



struct BBB : AAA

virtual bool run(double arg)

return false;

;


run has a different signature from run in AAA. This means that BBB::run(double) will hide AAA::run(int). Since it does, the only run that you can call from BBB is bool run(double arg). When you do



pb->run(5);


it finds bool BBB::run(double arg) as that is the only function you can call statically from a BBB and then virtual dispatch kicks in calling CCC::run(double)




In order to get the int version of the function to be called, you need to bring the int version into BBB. You can do this by writing one, or you could use using AAA::run; to import it in. Doing either of those will make pb->run(5); call the int version of run from CCC.




Don't forget, when playing with polymorphism you should declare the top level destructor (AAA's in this case) to be virtual. This allows you to delete objects correctly when using dynamic allocation. For full details see: When to use virtual destructors?






share|improve this answer



























  • >>This means that BBB::run(double) will hide AAA::run(int) I thought it will hide medhod only for BBB but not for CCC. In fact it is unclear for me. So the vtable will contain only one function. Right?

    – dimasafo
    8 hours ago












  • @JeJo: Through an AAA*, you would find float run(int) (and only that one, no possibility to call bool run(double))

    – Ben Voigt
    8 hours ago











  • @dimasafo Can't say about that. The reason the int version isn't called is because BBB can only call BBB::run(double), so that is the fucntion that virtual dispatch happens on. The int version is never considered.

    – NathanOliver
    8 hours ago











  • @dimasafo pb is a BBB, so only BBB's functions are considered. If you change pb to be a AAA* then the int version is called.

    – NathanOliver
    8 hours ago







  • 1





    Feels like using override here would have helped out a lot.

    – François Andrieux
    7 hours ago















6














When you do



struct BBB : AAA

virtual bool run(double arg)

return false;

;


run has a different signature from run in AAA. This means that BBB::run(double) will hide AAA::run(int). Since it does, the only run that you can call from BBB is bool run(double arg). When you do



pb->run(5);


it finds bool BBB::run(double arg) as that is the only function you can call statically from a BBB and then virtual dispatch kicks in calling CCC::run(double)




In order to get the int version of the function to be called, you need to bring the int version into BBB. You can do this by writing one, or you could use using AAA::run; to import it in. Doing either of those will make pb->run(5); call the int version of run from CCC.




Don't forget, when playing with polymorphism you should declare the top level destructor (AAA's in this case) to be virtual. This allows you to delete objects correctly when using dynamic allocation. For full details see: When to use virtual destructors?






share|improve this answer



























  • >>This means that BBB::run(double) will hide AAA::run(int) I thought it will hide medhod only for BBB but not for CCC. In fact it is unclear for me. So the vtable will contain only one function. Right?

    – dimasafo
    8 hours ago












  • @JeJo: Through an AAA*, you would find float run(int) (and only that one, no possibility to call bool run(double))

    – Ben Voigt
    8 hours ago











  • @dimasafo Can't say about that. The reason the int version isn't called is because BBB can only call BBB::run(double), so that is the fucntion that virtual dispatch happens on. The int version is never considered.

    – NathanOliver
    8 hours ago











  • @dimasafo pb is a BBB, so only BBB's functions are considered. If you change pb to be a AAA* then the int version is called.

    – NathanOliver
    8 hours ago







  • 1





    Feels like using override here would have helped out a lot.

    – François Andrieux
    7 hours ago













6












6








6







When you do



struct BBB : AAA

virtual bool run(double arg)

return false;

;


run has a different signature from run in AAA. This means that BBB::run(double) will hide AAA::run(int). Since it does, the only run that you can call from BBB is bool run(double arg). When you do



pb->run(5);


it finds bool BBB::run(double arg) as that is the only function you can call statically from a BBB and then virtual dispatch kicks in calling CCC::run(double)




In order to get the int version of the function to be called, you need to bring the int version into BBB. You can do this by writing one, or you could use using AAA::run; to import it in. Doing either of those will make pb->run(5); call the int version of run from CCC.




Don't forget, when playing with polymorphism you should declare the top level destructor (AAA's in this case) to be virtual. This allows you to delete objects correctly when using dynamic allocation. For full details see: When to use virtual destructors?






share|improve this answer















When you do



struct BBB : AAA

virtual bool run(double arg)

return false;

;


run has a different signature from run in AAA. This means that BBB::run(double) will hide AAA::run(int). Since it does, the only run that you can call from BBB is bool run(double arg). When you do



pb->run(5);


it finds bool BBB::run(double arg) as that is the only function you can call statically from a BBB and then virtual dispatch kicks in calling CCC::run(double)




In order to get the int version of the function to be called, you need to bring the int version into BBB. You can do this by writing one, or you could use using AAA::run; to import it in. Doing either of those will make pb->run(5); call the int version of run from CCC.




Don't forget, when playing with polymorphism you should declare the top level destructor (AAA's in this case) to be virtual. This allows you to delete objects correctly when using dynamic allocation. For full details see: When to use virtual destructors?







share|improve this answer














share|improve this answer



share|improve this answer








edited 7 hours ago

























answered 8 hours ago









NathanOliverNathanOliver

113k19 gold badges178 silver badges257 bronze badges




113k19 gold badges178 silver badges257 bronze badges















  • >>This means that BBB::run(double) will hide AAA::run(int) I thought it will hide medhod only for BBB but not for CCC. In fact it is unclear for me. So the vtable will contain only one function. Right?

    – dimasafo
    8 hours ago












  • @JeJo: Through an AAA*, you would find float run(int) (and only that one, no possibility to call bool run(double))

    – Ben Voigt
    8 hours ago











  • @dimasafo Can't say about that. The reason the int version isn't called is because BBB can only call BBB::run(double), so that is the fucntion that virtual dispatch happens on. The int version is never considered.

    – NathanOliver
    8 hours ago











  • @dimasafo pb is a BBB, so only BBB's functions are considered. If you change pb to be a AAA* then the int version is called.

    – NathanOliver
    8 hours ago







  • 1





    Feels like using override here would have helped out a lot.

    – François Andrieux
    7 hours ago

















  • >>This means that BBB::run(double) will hide AAA::run(int) I thought it will hide medhod only for BBB but not for CCC. In fact it is unclear for me. So the vtable will contain only one function. Right?

    – dimasafo
    8 hours ago












  • @JeJo: Through an AAA*, you would find float run(int) (and only that one, no possibility to call bool run(double))

    – Ben Voigt
    8 hours ago











  • @dimasafo Can't say about that. The reason the int version isn't called is because BBB can only call BBB::run(double), so that is the fucntion that virtual dispatch happens on. The int version is never considered.

    – NathanOliver
    8 hours ago











  • @dimasafo pb is a BBB, so only BBB's functions are considered. If you change pb to be a AAA* then the int version is called.

    – NathanOliver
    8 hours ago







  • 1





    Feels like using override here would have helped out a lot.

    – François Andrieux
    7 hours ago
















>>This means that BBB::run(double) will hide AAA::run(int) I thought it will hide medhod only for BBB but not for CCC. In fact it is unclear for me. So the vtable will contain only one function. Right?

– dimasafo
8 hours ago






>>This means that BBB::run(double) will hide AAA::run(int) I thought it will hide medhod only for BBB but not for CCC. In fact it is unclear for me. So the vtable will contain only one function. Right?

– dimasafo
8 hours ago














@JeJo: Through an AAA*, you would find float run(int) (and only that one, no possibility to call bool run(double))

– Ben Voigt
8 hours ago





@JeJo: Through an AAA*, you would find float run(int) (and only that one, no possibility to call bool run(double))

– Ben Voigt
8 hours ago













@dimasafo Can't say about that. The reason the int version isn't called is because BBB can only call BBB::run(double), so that is the fucntion that virtual dispatch happens on. The int version is never considered.

– NathanOliver
8 hours ago





@dimasafo Can't say about that. The reason the int version isn't called is because BBB can only call BBB::run(double), so that is the fucntion that virtual dispatch happens on. The int version is never considered.

– NathanOliver
8 hours ago













@dimasafo pb is a BBB, so only BBB's functions are considered. If you change pb to be a AAA* then the int version is called.

– NathanOliver
8 hours ago






@dimasafo pb is a BBB, so only BBB's functions are considered. If you change pb to be a AAA* then the int version is called.

– NathanOliver
8 hours ago





1




1





Feels like using override here would have helped out a lot.

– François Andrieux
7 hours ago





Feels like using override here would have helped out a lot.

– François Andrieux
7 hours ago










dimasafo is a new contributor. Be nice, and check out our Code of Conduct.









draft saved

draft discarded


















dimasafo is a new contributor. Be nice, and check out our Code of Conduct.












dimasafo is a new contributor. Be nice, and check out our Code of Conduct.











dimasafo is a new contributor. Be nice, and check out our Code of Conduct.














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%2f57577757%2fthe-logic-of-invoking-virtual-functions-is-not-clear-or-it-is-method-hiding%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

Sahara Skak | Bilen | Luke uk diar | NawigatsjuunCommonskategorii: SaharaWikivoyage raisfeerer: Sahara26° N, 13° O

The fall designs the understood secretary. Looking glass Science Shock Discovery Hot Everybody Loves Raymond Smile 곳 서비스 성실하다 Defas Kaloolon Definition: To combine or impregnate with sulphur or any of its compounds as to sulphurize caoutchouc in vulcanizing Flame colored Reason Useful Thin Help 갖다 유명하다 낙엽 장례식 Country Iron Definition: A fencer a gladiator one who exhibits his skill in the use of the sword Definition: The American black throated bunting Spiza Americana Nostalgic Needy Method to my madness 시키다 평가되다 전부 소설가 우아하다 Argument Tin Feeling Representative Gym Music Gaur Chicken 일쑤 코치 편 학생증 The harbor values the sugar. Vasagle Yammoe Enstatite Definition: Capable of being limited Road Neighborly Five Refer Built Kangaroo 비비다 Degree Release Bargain Horse 하루 형님 유교 석 동부 괴롭히다 경제력

19. јануар Садржај Догађаји Рођења Смрти Празници и дани сећања Види још Референце Мени за навигацијуу