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

Type conversion error in pointer to class member function

本文关键字:存在 类型转换 错误 指针 成员 函数      更新时间:2023-10-16

你好,这是我做的前一个问题的更新

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

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

错误消息:

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.h

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

Clip.cpp

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

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


我和一个朋友做了一些快速研究,找到了一种绕过这种情况的方法,这就是我们的发现。尽管这是有效的,但我们对所涉及的表达有一些疑问(文章末尾的问题(

Clip.h

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

Clip.cpp

void Clip::update(){
Callback function;
function = &Clip::func;
(this->*function)("a");
}

问题:

a-在上一篇文章中@tkausl回答道:"…成员函数指针与(非成员(函数指针不兼容"。这就是为什么其他代码不能在任何类中工作(即使该类完全为空(的原因吗?

b-如果我们已经在Clip类内部,为什么需要像thi:Clip::*Callback那样声明指针?

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

对于同样的回报,有没有更简单的方式或表达方式?

提前谢谢。

您确实遇到过指向成员函数的指针。它们与普通函数指针类似,但更细微,因为(非静态(成员函数总是隐式地传递一个特殊的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::function与lambdas:一起使用

// 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

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

什么要求?无法完成转换。如果你知道每个类型在任何时候都只分配一个回调,那么模板函数和局部静态变量有一种很好的方法。否则,尽量不要使用它们,有更安全的替代品,可以使用lambdas和std::function以c#方式绑定this。链路