In the example below, where I tried to reduce the problem to its minimal, there are 4 classes A,B,C,D., which form an inheritance hierarchy
When the program starts, an object d from class D is created and the test method of the D class is called. This method in turns calls the caller method of the C class. This method tries to use member function pointer to call the correct f method. In this case it should call the f method associated to class D but it calls the one associated to class B.
How come ?
class A {
public:
virtual void f() = 0;
};
class B : public A{
public:
virtual void f() { cout << "IN B" << endl;}
};
class C : public B{
public:
virtual void f() { B::f(); cout << "IN C" << endl; }
virtual void caller(){
void (A::*cb)() = NULL;
cb = &A::f;
(this->*cb)();
}
};
class D : public C{
public:
virtual void f() { C::f(); cout << "IN D" << endl; }
void test(){
caller();
}
};
int main(){
D d;
d.test(); // Why does this prints only "IN B"
return 0;
}
UPDATE : The code actually works, the problem had nothing to due with the presented code and seemed to come from a version mismatch between the library providing class A,B,C and the one providing class D.
You sure it prints only "IN B"? I compile it on MSVC2012, I got
IN B
IN C
IN D
What's more, your original code does not compile on VS2012, at least not before I add public
: to every class. e.g.:
class C : public B{
public: // <--- here
virtual void f() { B::f(); cout << "IN C" << endl; }
virtual void caller(){
void (A::*cb)() = NULL;
cb = &A::f;
(this->*cb)();
}
};
It prints
IN B
IN C
IN D
So, the problem is somewhere else.
it works. add public:
declaration. also warning about different behavior of overloading and virtualisation. best approach is to use pointer or reference.
class A {
public:
virtual void f() = 0;
};
class B : public A{
public:
virtual void f() { std::cout << "IN B" << std::endl;}
};
class C : public B{
public:
virtual void f() { B::f(); std::cout << "IN C" << std::endl; }
virtual void caller(){
void (A::*cb)() = NULL;
cb = &A::f;
(this->*cb)();
}
};
class D : public C{
public:
virtual void f() { C::f(); std::cout << "IN D" << std::endl; }
void test(){
caller();
}
};
output:
IN B
IN C
IN D
In the example below, where I tried to reduce the problem to its minimal, there are 4 classes A,B,C,D., which form an inheritance hierarchy
When the program starts, an object d from class D is created and the test method of the D class is called. This method in turns calls the caller method of the C class. This method tries to use member function pointer to call the correct f method. In this case it should call the f method associated to class D but it calls the one associated to class B.
How come ?
class A {
public:
virtual void f() = 0;
};
class B : public A{
public:
virtual void f() { cout << "IN B" << endl;}
};
class C : public B{
public:
virtual void f() { B::f(); cout << "IN C" << endl; }
virtual void caller(){
void (A::*cb)() = NULL;
cb = &A::f;
(this->*cb)();
}
};
class D : public C{
public:
virtual void f() { C::f(); cout << "IN D" << endl; }
void test(){
caller();
}
};
int main(){
D d;
d.test(); // Why does this prints only "IN B"
return 0;
}
UPDATE : The code actually works, the problem had nothing to due with the presented code and seemed to come from a version mismatch between the library providing class A,B,C and the one providing class D.
You sure it prints only "IN B"? I compile it on MSVC2012, I got
IN B
IN C
IN D
What's more, your original code does not compile on VS2012, at least not before I add public
: to every class. e.g.:
class C : public B{
public: // <--- here
virtual void f() { B::f(); cout << "IN C" << endl; }
virtual void caller(){
void (A::*cb)() = NULL;
cb = &A::f;
(this->*cb)();
}
};
It prints
IN B
IN C
IN D
So, the problem is somewhere else.
it works. add public:
declaration. also warning about different behavior of overloading and virtualisation. best approach is to use pointer or reference.
class A {
public:
virtual void f() = 0;
};
class B : public A{
public:
virtual void f() { std::cout << "IN B" << std::endl;}
};
class C : public B{
public:
virtual void f() { B::f(); std::cout << "IN C" << std::endl; }
virtual void caller(){
void (A::*cb)() = NULL;
cb = &A::f;
(this->*cb)();
}
};
class D : public C{
public:
virtual void f() { C::f(); std::cout << "IN D" << std::endl; }
void test(){
caller();
}
};
output:
IN B
IN C
IN D
0 commentaires:
Enregistrer un commentaire