在结构外部调用指向函数的指针

时间:2018-10-14 12:36:24

标签: c++ member-function-pointers

我有一个结构,在其中有一个指向相同结构起作用的指针。现在,我需要调用一个指针以在结构外部起作用。我举一个下面的代码示例:

#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;
}

2 个答案:

答案 0 :(得分:7)

(t.*tp)();试图调用成员函数指针tp,该成员函数指针在全局名称空间中定义为void (test::*tp)();,请注意实际上它已初始化为空指针(通过zero initialization 1 ),调用它会导致UB,一切皆有可能。

如果要调用对象tpt(即t.tp)的数据成员t,则应将其更改为

(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 关于零初始化

  

在以下情况下执行零初始化:

     

1)对于任何具有静态或线程本地存储持续时间that is not subject to constant initialization (since C++14)的命名变量,在进行任何其他初始化之前。

答案 1 :(得分:0)

@songyuanyao的答案是有效的。但是,您确定要以这种方式使用结构吗?为什么不只使用继承和虚拟方法呢? :

class base_test {
public:
    virtual void t() { std::cout << "test\n"; }
    void print() { t(); }
};

然后可以将其子类化:

class my_test : base_test {
public:
    virtual void t() { std::cout << "my test\n"; }
};

main()函数中(或任何位置),您可以具有返回基类的指针或引用的函数,而基类实际上是子类的实例。这样,您不必担心指针。

不利之处在于,您必须在编译时就了解不同的测试(如我刚才所解释的那样,甚至在使用现场也是如此)。如果您愿意,我会采用常见的习惯用法。