函数指针和虚函数
function pointer and virtual function
我想我的问题应该是愚蠢的,但这是真的,我从来没有见过一个函数指针被声明为虚拟。这有什么原因吗?
编辑:我应该说:它所指向的函数是否可能被指定为虚函数?
嗯,是(也不是)。
普通函数指针不能指向非静态成员函数。它们只能指向独立的函数,这就是为什么对于普通的函数指针来说,函数的虚拟性甚至不会出现在图中。
为了在c++中指向成员函数,你需要一个特殊类型的指针:具有指向成员函数类型的指针。这种类型的指针既可以指向非虚成员函数,也可以指向虚成员函数。如果要指向虚成员函数,则不需要采取特殊步骤。例如
struct B {
virtual void foo() {}
void bar() {}
};
...
B b;
void (B::*pfunc)(); // declare a pointer to a member function
pfunc = &B::foo; // make it point to `B::foo`
(b.*pfunc)(); // calls `B::foo` for object `b`
pfunc = &B::bar; // make it point to `B::bar`
(b.*pfunc)(); // calls `B::bar` for object `b`
然而,当您创建这样的指针指向虚成员函数时,您必须记住,它并不真正绑定到类层次结构中该函数的特定版本。关于要调用的特定函数的决定是在调用时做出的。例如
// given the above `B`
struct D : B {
virtual void foo() {}
};
...
void (B::*pfoo)(); // declare a pointer to a member function
pfoo = &B::foo; // and make it point to `B::foo`
在上面的例子中,我们让指针pfoo
指向B::foo
。还是我们?实际上,指针并没有硬链接到B::foo
。这两个调用
B b;
D d;
(b.*pfoo)();
(d.*pfoo)();
将调用两个不同的函数。第一个将为对象b
调用B::foo
,而第二个将为对象d
调用D::foo
,尽管我们在两种情况下使用了相同的指针值。这在许多应用程序中都是有意义的。
然而,在一些低级的情况下,将指针硬绑定到虚函数的特定版本是有用的。也就是说,如果有一个指针可以在执行
操作时调用d
对象的B
子对象的B::foo
(d.*pfoo)();
要实现这一点,我们需要能够指定是想要早绑定(在初始化时)还是晚绑定(在调用时)。不幸的是,c++语言没有提供这样的功能。
函数指针就是指向函数的指针。它只是存储函数的地址,就像任何指向type
的指针存储类型的地址一样。
关键字virtual
通过动态调度实现多态行为(基类和派生类的函数之间)。
考虑到上述两者明显不同,函数指针为虚指针的想法根本没有意义。
它所指向的函数是否被指定为virtual ?
正如我之前提到的,函数指针只是存储函数的地址。这只是一个type
。例如:
int *i = NULL;
void doSomething();
typedef void(*ptr)() = NULL;
ptr = &doSomething();
在上面的例子中:i
是int *
的一种。类似地,ptr
是一个存储不带参数也不返回参数的函数地址的类型。
所以,是的,从根本上说,你可以使函数指针指向的函数为虚函数,就像你可以通过在类中声明特定函数为虚函数来使任何函数为虚函数一样。
作为类型的函数指针可以指向具有该原型的任何函数,而将函数声明为虚函数意味着在特定的函数上启用动态分派,正如您所看到的,两者是不相同的。
虚性是成员函数的一个属性。如果你有一个指向虚成员函数的指针,那么将自动进行虚调用。常规函数不能是虚函数,因此虚函数指针没有意义。在这两种情况下,将函数指针设置为虚指针是没有意义的,因为它所指向的函数才算数。
- QMetaObject invokeMethod的基于函数指针的语法
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- c++r值引用应用于函数指针
- 模板函数指针和lambda
- 是否可以将llvm::FunctionType转换为C/C++原始函数指针
- 带有类的函数指针
- () 函子后面的括号,而不是函数指针?
- 全局作用域中函数指针的赋值
- 使用"Task"函数指针队列定义作业管理器
- 将成员函数指针作为参数传递给模板方法
- 如何创建对象函数指针C++映射?
- 匹配函数指针作为模板参数?
- 通过函数指针定义类范围之外的方法
- 存储在类中的函数指针
- C++从函数指针数组调用函数
- 将返回值存储在函数指针数组的指针中是如何工作的?
- 整数键映射到头文件中的成员函数指针
- 从类成员函数到类 C 函数指针的转换
- 如何将内联匿名函数分配给C++函数指针
- 将字符缓冲区强制转换为函数指针