【问题标题】:Class non-static method pointer to global function指向全局函数的类非静态方法指针
【发布时间】:2017-03-11 00:57:17
【问题描述】:

我试图将一个类方法指向一个全局函数,我见过this
但是没有实例我怎么能做到呢?

考虑一下:

class x
{
    public:
        int(x::*GetVal)(int);
};

int RtX(int a)
{
    return a * 4;
}

// declaration
int(x::*GetVal)(int) = (int(x::*)(int))&::Rtx; // :: global? // error

int main()
{
    x a;
    cout << (a.*GetVal)(4) << endl; 
}

这会返回错误:

[错误] 从类型 'int ()(int)' 到类型 'int 的无效转换 (x::)(int)'

【问题讨论】:

  • 改用std::functionstd::bind
  • 至于你的错误,成员函数和非成员函数不一样。成员函数需要调用对象的实例,非成员函数不需要。该对象实例通常作为隐藏参数传递给成员函数,并且由于非成员函数没有该隐藏参数,因此它们在任何方面、形状或形式上都不兼容。
  • 作为绑定的替代方法,您还可以使用一个 Lamba,您可以在其中调用成员函数并将其存储在 std::function 对象中。
  • 另一件事,这使整个事情变得更加不清楚。你想做什么?当它不是静态的时,您不能将函数指针设置为没有实例的类。你需要一个实例化。您想要静态函数指针还是默认函数指针?

标签: c++ pointers c++14


【解决方案1】:

x::GetX 是指向成员的指针。这些是非常复杂的野兽,你不能让它们指向非成员函数。以下代码将起作用:

#include <iostream>

int RtX(int a)   // Global non-member function
{
    return a * 4;
}

class x
{
    public:

        int(x::*GetVal)(int);

        // This is an instance member function which acts as a proxy and calls the
        // the global function
        int RtX(int a) { return ::RtX(a); }
};


int main()
{
    x a;
    a.GetVal =&x.RtX;  // Assign the member variable.  Could do this in the
                       // constructor.  **NOTE** No casts!
    std::cout << (a.*GetVal)(4) << std::endl; 
}

如果你在处理函数指针和指向成员函数的指针时发现自己需要强制转换,stop - 你几乎肯定做错了,虽然它会编译,但它是很可能无法正常运行。

或者,如 cmets 中所述,使用 std::function

#include <iostream>
#include <functional>

int RtX(int a)
{
    return a * 4;
}

class x
{
public:
    std::function<int(int)> GetVal;

    // Initialize GetVal in the constructor.
    x() : GetVal(RtX) 
    {}

    // Alternatively, you can initialize the variable in with a default
    // initialization.  You can also declare the member const if you don't want to 
    // change it later.

    const std::function<int(int)> gv = RtX;

    /*
};

int main()
{
    x a;
    std::cout << a.GetVal(4) << std::endl; 
}

【讨论】:

  • 好点。没有注意到标题中的“非静态”。我会修改的。
  • 我知道这可能是静态的,但我想知道是否可以做非静态的。非常感谢您的帮助。
  • 静态无法实现您所拥有的。我已经更新为非静态。
  • 这是唯一的快速解决方案,我将框架作为解决方案,@Martin Bonner 请您告诉我是否可以将其声明出类,例如 x::gv = Rtx; (课外)。?
  • ... 这就是说“不,你不能在类外为非静态成员写x::gv = Rtx”。 @nikomaster
【解决方案2】:

非静态成员函数需要一个实例才能被调用。您可能会考虑使用静态函数成员,如果您还使用std::function,您可能会得到一个简单的代码来分配您的成员函数而无需实例:

#include <iostream>
#include <functional>

int RtX(int a)
{
    return a * 4;
}

class x
{
public:
    static std::function<int(int)> GetVal;
};

std::function<int(int)> x::GetVal = RtX;

int main()
{
    x a;
    std::cout << (a.GetVal)(4) << std::endl;
}

【讨论】:

    猜你喜欢
    • 2011-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-24
    • 2018-01-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多