在结构外调用指向函数的指针
Call a pointer-to-function outside the structure
我有一个结构,里面有一个指向同一结构函数的指针。现在我需要调用一个指向结构外部函数的指针。我给出了以下代码的示例:
#include <iostream>
struct test {
void (test::*tp)(); // I need to call this pointer-to-function
void t() {
std::cout << "test\n";
}
void init() {
tp = &test::t;
}
void print() {
(this->*tp)();
}
};
void (test::*tp)();
int main() {
test t;
t.init();
t.print();
(t.*tp)(); // segfault, I need to call it
return 0;
}
(t.*tp)();
试图调用在全局命名空间定义为 void (test::*tp)();
的成员函数指针 tp
,请注意它实际上被初始化为空指针(通过 zero initialization1), invoking it leads to UB, 一切皆有可能。
如果要在对象t
上调用t
(即t.tp
)的数据成员tp
,则应将其更改为
(t.*(t.tp))();
^
|
---- object on which the member function pointed by tp is called
如果你确实想调用全局tp
,你应该适当地初始化它,比如
void (test::*tp)() = &test::t;
那么你可以
(t.*tp)(); // invoke global tp on the object t
1关于零初始化
Zero initialization is performed in the following situations:
1) For every named variable with static or thread-local storage duration that is not subject to constant initialization (since C++14)
, before any other initialization.
@songyuanyao 的回答有效。但是,您确定要那样使用您的结构吗?为什么不直接使用继承和虚拟方法呢? :
class base_test {
public:
virtual void t() { std::cout << "test\n"; }
void print() { t(); }
};
然后你可以子class它:
class my_test : base_test {
public:
virtual void t() { std::cout << "my test\n"; }
};
在您的 main()
函数(或任何地方)中,您可以让函数返回指向基 class 的指针或引用,它们实际上是 subclasses 的实例。这样,您就不必担心指针了。
缺点是您必须在编译时了解您的不同测试(而且甚至在使用站点时也不知道,正如我刚才解释的那样)。如果你这样做,我会使用常见的成语。
我有一个结构,里面有一个指向同一结构函数的指针。现在我需要调用一个指向结构外部函数的指针。我给出了以下代码的示例:
#include <iostream>
struct test {
void (test::*tp)(); // I need to call this pointer-to-function
void t() {
std::cout << "test\n";
}
void init() {
tp = &test::t;
}
void print() {
(this->*tp)();
}
};
void (test::*tp)();
int main() {
test t;
t.init();
t.print();
(t.*tp)(); // segfault, I need to call it
return 0;
}
(t.*tp)();
试图调用在全局命名空间定义为 void (test::*tp)();
的成员函数指针 tp
,请注意它实际上被初始化为空指针(通过 zero initialization1), invoking it leads to UB, 一切皆有可能。
如果要在对象t
上调用t
(即t.tp
)的数据成员tp
,则应将其更改为
(t.*(t.tp))();
^
|
---- object on which the member function pointed by tp is called
如果你确实想调用全局tp
,你应该适当地初始化它,比如
void (test::*tp)() = &test::t;
那么你可以
(t.*tp)(); // invoke global tp on the object t
1关于零初始化
Zero initialization is performed in the following situations:
1) For every named variable with static or thread-local storage duration
that is not subject to constant initialization (since C++14)
, before any other initialization.
@songyuanyao 的回答有效。但是,您确定要那样使用您的结构吗?为什么不直接使用继承和虚拟方法呢? :
class base_test {
public:
virtual void t() { std::cout << "test\n"; }
void print() { t(); }
};
然后你可以子class它:
class my_test : base_test {
public:
virtual void t() { std::cout << "my test\n"; }
};
在您的 main()
函数(或任何地方)中,您可以让函数返回指向基 class 的指针或引用,它们实际上是 subclasses 的实例。这样,您就不必担心指针了。
缺点是您必须在编译时了解您的不同测试(而且甚至在使用站点时也不知道,正如我刚才解释的那样)。如果你这样做,我会使用常见的成语。