以下段落摘自 Stroustup 书“The C++ Programming Language”(第三版)的第 420 页:
因为指向虚拟成员(本例中为 s)的指针是一种偏移量,所以它不依赖于对象在内存中的位置。因此,只要在两个地址空间中使用相同的对象布局,指向虚拟成员的指针就可以安全地在不同地址空间之间传递。与指向普通函数的指针一样,指向非虚拟成员函数的指针不能在地址空间之间交换。
我对本段的最后一句话提出异议。下面,您将找到一个代码片段,其中指向非虚拟成员函数foo()
和的指针在一个基础对象和派生对象foo1()
之间进行交换,没有问题。a
b
不能重载基类foo()
或foo1()
派生类中的任何函数,因为在这种情况下,编译器将发出如下所示的错误。
#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)();
}