samedi 19 avril 2014

classe - comportement inattendu des fonctions virtuelles C++ - Stack Overflow


I've got this cod:


class First{
public:
virtual void print(){cout<<"First";}

};

class Second : public First {
public:
virtual void print(){cout<<"Second";}


};
class Third : public Second{
public:
void print(){cout<<"Third";}

int main(){
Third ob;
ob.print();
Second& sec=ob;
sec.print();
First& frs=ob;
frs.print();
}

Everything turns out as i expected, all 3 print: "Third".


Now because i have too much code and it is basically the same with a little change i will discuss it in the text.


Now i remove virtual from print in First and it prints out: "Third Third First" as i expected.


This third time, i put back virtual in First, but i remove it from Second. Now it prints: "Third Third Third". Hmm, that's not what i expected. Lets say that when with reference First it sees that the function is virtual it then checks the objects and invokes the method for Third, but when with reference Second it sees that the function is not virtual why does it still invoke Third's print?




If a function overrides a virtual function, then it's virtual whether or not you explicitly declare it so. So here Second::print is virtual, however you declare it.




Function is considered virtual if it's declared as virutal or if it's declared as virtual in any of it's base classes (when called via pointer or reference).




The behaviour in the last case is expected. You are using references to an object of type Third. So the virtual function of this class is called in all three calls. You removed declaration of the function in class Second but the cvlass inherits this function from class First. It only does not override it.



I've got this cod:


class First{
public:
virtual void print(){cout<<"First";}

};

class Second : public First {
public:
virtual void print(){cout<<"Second";}


};
class Third : public Second{
public:
void print(){cout<<"Third";}

int main(){
Third ob;
ob.print();
Second& sec=ob;
sec.print();
First& frs=ob;
frs.print();
}

Everything turns out as i expected, all 3 print: "Third".


Now because i have too much code and it is basically the same with a little change i will discuss it in the text.


Now i remove virtual from print in First and it prints out: "Third Third First" as i expected.


This third time, i put back virtual in First, but i remove it from Second. Now it prints: "Third Third Third". Hmm, that's not what i expected. Lets say that when with reference First it sees that the function is virtual it then checks the objects and invokes the method for Third, but when with reference Second it sees that the function is not virtual why does it still invoke Third's print?



If a function overrides a virtual function, then it's virtual whether or not you explicitly declare it so. So here Second::print is virtual, however you declare it.



Function is considered virtual if it's declared as virutal or if it's declared as virtual in any of it's base classes (when called via pointer or reference).



The behaviour in the last case is expected. You are using references to an object of type Third. So the virtual function of this class is called in all three calls. You removed declaration of the function in class Second but the cvlass inherits this function from class First. It only does not override it.


0 commentaires:

Enregistrer un commentaire