指向类成员函数的指针中的类型转换错误

时间:2018-07-17 18:31:47

标签: c++ class pointers function-pointers class-members

您好,这是this previous question i did

的更新

我试图通过类内部的指针执行函数(类内容与我遇到的问题无关)。

这是上一个问题发布的代码:

错误消息:

    POST /azzeraContatori HTTP/1.1
Host: 192.168.1.1
Content-Type: application/json
Origin: http://192.168.1.1
Accept-Language: it-it
Accept-Encoding: gzip, deflate
Connection: keep-alive
Accept: application/json, text/javascript, */*; q=0.01
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 11_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Mobile/15E148 Safari/604.1
Referer: http://192.168.1.1/contatori.html
Content-Length: 17
X-Requested-With: XMLHttpRequest

Clip.h

cannot convert ‘Clip::func’ from type ‘void (Clip::)(std::string) {aka void (Clip::)(std::basic_string<char>)}’ to type ‘callback {aka void (*)(std::basic_string<char>)}’

Clip.cpp

void func(string str){
    cout << str << endl;
}

------我找到的解决方案------


我和一个朋友做了一些快速研究,以找到解决这种情况的方法,这就是我们所发现的。即使这种方法行得通,但我们对涉及的expresios有一些疑问(帖子末尾的问题)

Clip.h

void Clip::update(){
    typedef void(*callback)(string);
    callback callbackFunction = func;
    callbackFunction("called");
}

Clip.cpp

    typedef  void (Clip::*Callback) (string);
    void func(string _val);

问题:

a-在上一篇文章@tkausl中回答:“ ...成员函数指针与(非成员)函数指针不兼容”。这就是为什么其他代码无法在任何类内部运行的原因(即使该类完全为空)?

b-如果我们已经在Clip类中了,为什么必须像thi这样声明指针: Clip :: * Callback

c-这个表达式是什么意思?: this-> * function

d-是否有更简单的方法或表达方式来满足相同的要求?

提前谢谢。

2 个答案:

答案 0 :(得分:1)

您确实遇到过pointers to member functions。它们与普通函数指针相似,但更为细微,因为(非静态)成员函数始终隐式地将一个特殊的this参数传递给它们,该参数引用当前的对象该函数被调用。该秘密this参数是根据包含该函数的类强烈键入的。这就是为什么类名也是成员函数类型的指针的一部分的原因。这也是它们不与常规函数指针混合的原因。这是一个基本示例:

// Declaration of a pointer to member function
// Note that no object is used here
void (ClassName::*my_fn_pointer)(ParameterTypes);

// Assignment also doesn't use an object
my_pointer = &ClassName::exampleMemberFunction;

// But to invoke the method, you need an object
ClassName obj;
(obj::*my_fn_pointer)(example_params);

// Alternatively, inside a member function of ClassName:
(this->*my_fn_pointer)(example_params);

有很多选择。我看不到您的其余代码以及您要解决的问题,因此我的建议有限。不过,我赞同将std::functionlambdas一起使用:

// std::function generically wraps a callable type
std::function<void(ParamTypes)> my_fn;


// Using an object:
ClassName obj;
// lambda declaration
my_fn = [&obj](ParamTypes params){
    // 'obj' is captured by reference, so make sure it stays alive as long as needed
    obj.chooseYourMemberFunctionHere(params);
};

// function is called here, syntax is easier on the eyes
my_fn(example_params);


// Using 'this' inside a member function:
my_fn = [this](ParamTypes params){
    // 'this' is captured by reference
    // also make sure the current object stays alive alive as long as needed
    this->chooseYourMemberFunctionHere(params);
};

my_fn(example_params); // function is called here

答案 1 :(得分:0)

A

它与您编写代码的位置无关。成员函数指针和函数指针是两种不同类型的指针。您的代码无效,因为您无法将成员函数指针分配给普通函数指针。如果可以考虑这段代码,它的输出应该是什么?

class Foo
{
public:
    Foo(int x) :x(x) {}
    void bar(int y)
    {
        std::cout << x+y;
    }
    int x;
}
int main()
{
    typedef void(*callback)();

    callback ptr = &Foo::bar;//Won't compile with same error as in your question

    ptr(5);
}

没有Foo的实例,因此没有要打印的x。与C#不同,C ++不允许您捕获this,因此Foo f; callback ptr = &f::bar也不会编译。您可以考虑将Foo::bar等同于

void bar(Foo* this,int y)
{
   std::cout<< this->x+y;
}

现在您看到那些功能类型确实不同。

B

您可以从bar的翻译上方看到,必须指定this的类型,无论您在何处编写该代码。

C

调用成员函数是通过->*运算符完成的,其左侧恰好是缺少的this指针,而右侧是成员函数指针变量和参数。参见:

Foo foo;
typedef void(Foo::callback)(int);//Member pointer
callback ptr = &Foo::bar;//Now OK
Foo* thisFoo = &foo;//Left-hand side must be a pointer to Foo
(thisFoo->*ptr)(5);//equivalent to foo->bar(5);

this->*function只是意味着调用存储在function变量中的成员函数,并使用this指针作为实例。

D

有什么要求?转换无法完成。如果您知道每时每刻只为每种类型分配一个回调,则可以使用模板方法和局部静态变量的一种有效方式。否则请尝试不使用它们,可以使用lambda和std::function的更安全替代方法,它们可以以c#方式绑定thislink