Topic: virtuality and explicit qualification conflict ?


Author: freja@mip3035.Berkeley.EDU (Etienne Frejaville)
Date: 20 Jul 94 08:55:50 GMT
Raw View
Hi C++ world ...

A netter has recently pointed out that it was impossible to
break virtuality on a member function call through a
pointer to member function.

Indeed, only explicit qualification on a direct member function
call can break virtuality. The fact of taking the address of a
qualified base member function and calling it through a pointer
to member function never breaks virtuality.

example :

#include <iostream.h>
class A {
 public :
 virtual void f() { cout << "in A::void f()" << endl; }
};
class B : public A {
 public :
 void f() { cout << "in B::void f()" << endl; }
};
main () {
 A *pa;B b;
 pa=&b;
 pa->f(); // B::f called : normal case of virtuality
 pa->A::f(); // A::f called : virtuality broken
 void (A::*pf)()=&A::f;
 (pa->*pf)(); // B::f called : virtuality NOT broken
}

My first question is : Why the language doesn't provide any
syntactic mean to break virtuality on the call :

 (pa->*pf)();

Besides, would it be possible ... ?

But this problem has led me to another. I have discovered that
in some cases, the fact that the scope operator necessary to make
visible hidden information was also used to break virtuality was
very inconvenient and that in that case, the use of pointers to
member functions was the only work around.

example :

#include <iostream.h>
class A {
 public :
 virtual int f() =0;
};
class B : public A {
 public :
 virtual int f(int n) {
   // Here we want to express f(int) with f() i.e
   // f(n) = n * f()
   // but we can't write : return n * f()
   // as f() is hidden by f(int). Neither A::f() can be used
   // as it would break virtuality and moreover it doesn't work
   // as f() is pure. The only way is to use a pointer to m.f :
  int (A::*pf)()=&A::f;
  return n * (this->*pf)();
 }
};
class C : public B {
 public :
 int f() { cout << "in C::int f()" << endl; return 2;}
};
main () {
 B *pb;C c;
 pb=&c;
 cout << pb->f(2); // returns 4 : ok
}

So my second question is : is it convenient to use the same
operator for scope qualification and to break virtuality ?
More generally, is not normal that in some case,
pointer to member functions must be used as a work around to
express what cannot be expressed otherwise ?

Any ideas ?


------Etienne FREJAVILLE--- Bull S.A   ---------------------------------
 OSS/HEU/ASD/TOPAS                      e-mail: E.Frejaville@frcl.bull.fr
 Rue Jean-Jaures, F5-238                tel: (33-1) 30806548
 78340 Les Clayes-sous-Bois, France     Fax: (33-1) 30803338






Author: E.Frejaville@frcl.bull.fr (Etienne Frejaville)
Date: 20 Jul 94 11:08:24 GMT
Raw View
Hi C++ world ...

A netter has recently pointed out that it was impossible to
break virtuality on a member function call through a
pointer to member function.

Indeed, only explicit qualification on a direct member function
call can break virtuality. The fact of taking the address of a
qualified base member function and calling it through a pointer
to member function never breaks virtuality.

example :

#include <iostream.h>
class A {
 public :
 virtual void f() { cout << "in A::void f()" << endl; }
};
class B : public A {
 public :
 void f() { cout << "in B::void f()" << endl; }
};
main () {
 A *pa;B b;
 pa=&b;
 pa->f(); // B::f called : normal case of virtuality
 pa->A::f(); // A::f called : virtuality broken
 void (A::*pf)()=&A::f;
 (pa->*pf)(); // B::f called : virtuality NOT broken
}

My first question is : Why the language doesn't provide any
syntactic mean to break virtuality on the call :

 (pa->*pf)();

Besides, would it be possible ... ?

But this problem has led me to another. I have discovered that
in some cases, the fact that the scope operator necessary to make
visible hidden information was also used to break virtuality was
very inconvenient and that in that case, the use of pointers to
member functions was the only work around.

example :

#include <iostream.h>
class A {
 public :
 virtual int f() =0;
};
class B : public A {
 public :
 virtual int f(int n) {
   // Here we want to express f(int) with f() i.e
   // f(n) = n * f()
   // but we can't write : return n * f()
   // as f() is hidden by f(int). Neither A::f() can be used
   // as it would break virtuality and moreover it doesn't work
   // as f() is pure. The only way is to use a pointer to m.f :
  int (A::*pf)()=&A::f;
  return n * (this->*pf)();
 }
};
class C : public B {
 public :
 int f() { cout << "in C::int f()" << endl; return 2;}
};
main () {
 B *pb;C c;
 pb=&c;
 cout << pb->f(2); // returns 4 : ok
}

So my second question is : is it convenient to use the same
operator for scope qualification and to break virtuality ?
More generally, is not normal that in some case,
pointer to member functions must be used as a work around to
express what cannot be expressed otherwise ?

Any ideas ?

------Etienne FREJAVILLE--- Bull S.A   ---------------------------------
 OSS/HEU/ASD/TOPAS                      e-mail: E.Frejaville@frcl.bull.fr
 Rue Jean-Jaures, F5-238                tel: (33-1) 30806548
 78340 Les Clayes-sous-Bois, France     Fax: (33-1) 30803338