mercredi 16 avril 2014

héritage - C++ membres fonction virtuelle redéfinie et surcharge en même temps - Stack Overflow


If I have a code like this:


struct A {
virtual void f(int) {}
virtual void f(void*) {}
};

struct B : public A {
void f(int) {}
};

struct C : public B {
void f(void*) {}
};


int main() {
C c;
c.f(1);

return 0;
}

I get an error that says that I am trying to do an invalid conversion from int to void*. Why can't compiler figure out that he has to call B::f, since both functions are declared as virtual?






After reading jalf's answer I went and reduced it even further. This one does not work as well. Not very intuitive.


struct A {
virtual void f(int) {}
};

struct B : public A {
void f(void*) {}
};


int main() {
B b;
b.f(1);

return 0;
}



The short answer is "because that's how overload resolution works in C++".


The compiler searches for functions F inside the C class, and if it finds any, it stops the search, and tries to pick a candidate among those. It only looks inside base classes if no matching functions were found in the derived class.


However, you can explicitly introduce the base class functions into the derived class' namespace:


struct C : public B {
void f(void*) {}
using B::f; // Add B's f function to C's namespace, allowing it to participate in overload resolution
};



I was a bit doubtful about that one, but indeed it does not compile. Here is a simplified version of the code that illustrates the same issue.


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

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

int main() {
B b;
b.f(1);
return 0;
}



Or you could do this:


void main()
{
A *a = new C();
a->f(1); //This will call f(int) from B(Polymorphism)
}



Well I think first of all you did not understand what virtual mechanism or polymorhism. When the polymorphism is achieved only by using object pointers. I think you are new to c++. Without using object pointers then there is no meaning of polymorphism or virtual keyword use base class pointer and assign the desired derived class objects to it. Then call and try it.



If I have a code like this:


struct A {
virtual void f(int) {}
virtual void f(void*) {}
};

struct B : public A {
void f(int) {}
};

struct C : public B {
void f(void*) {}
};


int main() {
C c;
c.f(1);

return 0;
}

I get an error that says that I am trying to do an invalid conversion from int to void*. Why can't compiler figure out that he has to call B::f, since both functions are declared as virtual?






After reading jalf's answer I went and reduced it even further. This one does not work as well. Not very intuitive.


struct A {
virtual void f(int) {}
};

struct B : public A {
void f(void*) {}
};


int main() {
B b;
b.f(1);

return 0;
}


The short answer is "because that's how overload resolution works in C++".


The compiler searches for functions F inside the C class, and if it finds any, it stops the search, and tries to pick a candidate among those. It only looks inside base classes if no matching functions were found in the derived class.


However, you can explicitly introduce the base class functions into the derived class' namespace:


struct C : public B {
void f(void*) {}
using B::f; // Add B's f function to C's namespace, allowing it to participate in overload resolution
};


I was a bit doubtful about that one, but indeed it does not compile. Here is a simplified version of the code that illustrates the same issue.


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

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

int main() {
B b;
b.f(1);
return 0;
}


Or you could do this:


void main()
{
A *a = new C();
a->f(1); //This will call f(int) from B(Polymorphism)
}


Well I think first of all you did not understand what virtual mechanism or polymorhism. When the polymorphism is achieved only by using object pointers. I think you are new to c++. Without using object pointers then there is no meaning of polymorphism or virtual keyword use base class pointer and assign the desired derived class objects to it. Then call and try it.


0 commentaires:

Enregistrer un commentaire