Il paragrafo che segue è stato estratto da pagina 420 da Stroustup libro "The C++ Programming Language" (terza edizione):Penso che la seguente affermazione sia errata o mi manchi qualcosa?
Perché un puntatore a un membro virtuale (s in questo esempio) è una sorta di offset, non dipende dalla posizione di un oggetto in memoria. Un puntatore a un membro virtuale può quindi essere passato in modo sicuro tra spazi di indirizzi diversi a condizione che sia utilizzato lo stesso layout di oggetto in entrambi. Come i puntatori alle funzioni ordinarie, i puntatori alle funzioni membro non virtuali non possono essere scambiati tra spazi di indirizzi.
Sto discutendo l'ultima frase in questo paragrafo. Di seguito, troverai uno snippet di codice in cui i puntatori alle funzioni membro non virtuali foo()
e vengono scambiati tra un oggetto di base a
e un oggetto derivato b
, senza problemi.
Ciò che non può essere fatto è il sovraccarico di una qualsiasi delle funzioni nella base, foo()
o foo1()
, nella classe derivata, poiché in questo caso il compilatore emetterà un errore come mostrato di seguito.
#include <iostream>
class A
{
int i;
public:
A() : i(1) {}
void foo() { std::cout << i << '\n'; }
void foo1() { std::cout << 2 * i << '\n'; }
};
class B: public A
{
int j;
public:
B() : A(), j(2) {}
// void foo() { std::cout << j << '\n'; }
};
int main()
{
typedef void (A::* PMF)();
PMF p = &B::foo; // error C2374: 'p' redefinition, multiple initialization
// if foo() is overloaded in B.
PMF q = &B::foo1;
B b;
(b.*p)();
(b.*q)();
A a;
(a.*p)();
(a.*q)();
}
La mia lettura di "scambio tra spazi di indirizzi" era qualcosa come una trasmissione diretta di un puntatore a * un altro processo * in un sistema operativo. – ulidtko