【问题标题】:Call a pointer-to-function outside the structure在结构外调用函数指针
【发布时间】:2018-10-14 12:36:23
【问题描述】:

我有一个结构,里面有一个指向同一结构的函数的指针。现在我需要调用一个指向结构外函数的指针。我举一个下面的代码示例:

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

【问题讨论】:

  • void (test::*tp)(); - 你为什么在课外有这个。删除它并修复你的调用语法。

标签: c++ member-function-pointers


【解决方案1】:

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

如果要在对象t上调用t的数据成员tp(即t.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关于零初始化

以下情况会进行零初始化:

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

【讨论】:

    【解决方案2】:

    @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() 函数(或任何地方)中,您可以有函数返回指向基类的指针或引用,它们实际上是子类的实例。这样一来,您就不必担心指针了。

    缺点是您必须在编译时了解您的不同测试(甚至在使用站点,正如我刚刚解释的那样)。如果你这样做,我会用常见的成语。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-13
      • 1970-01-01
      • 2015-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多