指向基本虚成员函数的指针
Pointer to a base virtual member function
如果基class中的成员函数是虚函数并且在派生class中被覆盖,有没有办法在成员函数上创建指针?
考虑如下代码
#include <iostream>
#include <functional>
struct Base
{
virtual void g() const
{
std::cout << "Base" << std::endl;
}
};
struct Derived : Base
{
virtual void g() const override
{
std::cout << "Derived" << std::endl;
}
};
int main()
{
Derived d;
(d.*(&Base::g))();
std::mem_fn(&Base::g)(d);
return 0;
}
尽管我在 Base::g 上做了一个指针,它还是打印了两次“Derived”。有没有办法让函数 g 保持虚拟和重写,并获取将为 d 打印“Base”的成员函数指针?
您可以定义一个从 g
调用的非虚函数 real_g
所以代码
struct Base
{
void real_g() const {
std::cout << "Base" << std::endl;
}
virtual void g() const { real_g(); };
};
然后在 main
std::mem_fn(&Base::real_g)(d);
请参阅 virtual method table, this C++ reference and the C++ standard n3337 or better. Read also a good C++ programming book and the documentation of your C++ compiler, e.g. GCC
上的维基页面
另见 答案(在简单情况下天真地解释什么是虚表)
只需调用基函数
int main()
{
Derived d;
d.g();
Base* b = &d;
b->Base::g();
//or
d.Base::g();
//or
auto callLater = [&d]() { d.Base::g();};
callLater();
return 0;
}
输出
Derived
Base
Base
Base
这可以作为函数的指针;但它需要指向所指向对象的成员函数 Base::g()。
如果基class中的成员函数是虚函数并且在派生class中被覆盖,有没有办法在成员函数上创建指针?
考虑如下代码
#include <iostream>
#include <functional>
struct Base
{
virtual void g() const
{
std::cout << "Base" << std::endl;
}
};
struct Derived : Base
{
virtual void g() const override
{
std::cout << "Derived" << std::endl;
}
};
int main()
{
Derived d;
(d.*(&Base::g))();
std::mem_fn(&Base::g)(d);
return 0;
}
尽管我在 Base::g 上做了一个指针,它还是打印了两次“Derived”。有没有办法让函数 g 保持虚拟和重写,并获取将为 d 打印“Base”的成员函数指针?
您可以定义一个从 g
调用的非虚函数 real_g
所以代码
struct Base
{
void real_g() const {
std::cout << "Base" << std::endl;
}
virtual void g() const { real_g(); };
};
然后在 main
std::mem_fn(&Base::real_g)(d);
请参阅 virtual method table, this C++ reference and the C++ standard n3337 or better. Read also a good C++ programming book and the documentation of your C++ compiler, e.g. GCC
上的维基页面另见
只需调用基函数
int main()
{
Derived d;
d.g();
Base* b = &d;
b->Base::g();
//or
d.Base::g();
//or
auto callLater = [&d]() { d.Base::g();};
callLater();
return 0;
}
输出
Derived
Base
Base
Base
这可以作为函数的指针;但它需要指向所指向对象的成员函数 Base::g()。